#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12

    Question findfirst() and findnext()


    Hi,
    I am trying to develop a program in C++ that is a playlist generator. I want to put in a random disk (CD-ROM) and have it scan for .mp3 files in there and create playlists based on what directory they are in. (The directories are album names). How do I use findfirst() and findnext() to do this? (Also, I need LFN support) Please advise.

    P.S.: Is there a way that I can also send retrieve info to CDDB through this to get the track order?

    NOTE: I am using CodeWarrior and Turbo C++ 3.0
    Last edited by macrohard; February 22nd, 2003 at 09:54 AM.
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    See this thread: Traverse an NTFS Directory
    IIRC, findfirst() and findnext() were calls from the days of DOS and the new Windows calls are called FindFirstFile(), FindNextFile() and FindClose(). findfirst() and findnext() are still supported, but they only get the short file names, not the long names (i.e. something like "MYDOCU~1" instead of "My Documents"). Hope this helps! :)
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    Great! What's the syntax and reqired header files to use these? And just to make sure, it will work under DOS as long as Windows is running? If not, pls tell me the conditions under which it will work. Thanks; please repond promptly!
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    >> What's the syntax and reqired header files to use these?
    When in doubt, check in msdn.microsoft.com. Your documentation for these functions is here

    This should work under Windows, whether you run a console program or a program with dialog boxes. The only requirement is that you tell your compiler to make a Windows executable.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    I checked MSDN, only to find that it searches for a name rather than a type. I want ALL DIRECTORIES, no matter what name, rather than every file/directory that matches a given name. Please advise.
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    I posted the MSDN link because I thought you wanted the syntax and documentation for these functions. For something that searches all directories/files, see my first link -- that's EXACTLY what the code did.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    "The FindFirstFile function searches a directory for a file whose name matches the specified file name. FindFirstFile examines subdirectory names as well as file names."

    I don't want to search for a name, I want to search for a type, and have it return the names of All Directories that match the given type. (Requested type: Directories)
  14. #8
  15. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    >> I want to search for a type, and have it return the names of All Directories that match the given type. (Requested type: Directories)
    Then you request all entries with FindFirstFile and check the dwFileAttributes member of WIN32_FIND_DATA structure to see if it is a directory or a file. Have you been checking my sample code out or not, because this is EXACTLY what my sample code does. I even went through the trouble of commenting almost everything in that sample.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    I'm not getting the full gist of this (SORRY!). Could you please give me the syntax for this?
    Last edited by macrohard; February 26th, 2003 at 04:04 PM.
  18. #10
  19. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    Ok, here's a snippet and I'm going to explain what it does line by line. So grab yourself a drink and relax:
    Code:
    HANDLE hFind;
    BOOL bContinue = TRUE;
    WIN32_FIND_DATA data;
    
    hFind = FindFirstFile("*.*", &data); 
    
    // If we have no error, loop thru the files in this dir
    while (hFind && bContinue) {
    	// Check if this entry is a directory
    	if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    		// This is a directory
    	}	
    	bContinue = FindNextFile(hFind, &data);
    }
    FindClose(hFind); // Free the dir structure
    In the line hFind = FindFirstFile(...) we ask FindFirstFile to start fetching everything from the current directory, by specifying *.*. This will return us a handle, which we save in hFind, so that we can use if for FindNextFile(). Then we check the attributes of the first entry returned by FindFirstFile by checking data.dwFileAttributes to see if the directory bit is set. If the directory bit is set, then this is a directory. If not, it is a normal file. You can get the rest of the elements of the variable "data" by checking the MSDN documention (the other elements contain information such as name, size, creation date etc.) Then we call FindNextFile() to get the next entry. We continue to call FindNextFile() until it returns FALSE to indicate that there are no more entries within this directory. Finally we call FindClose() to free the resources allocated. This is the BASICS for finding all the sub-dirs and files in ONE directory.

    If you want it to go down a directory tree, you can call the function recursively to go down the tree. If you look at my first link at the beginning of this thread, that's what that function does. It recursively works its way down from the root directory, all the way down to every directory in the drive.

    Hope this helps :)
    Last edited by Scorpions4ever; February 26th, 2003 at 04:19 PM.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    Do I heed to include <windows.h>? Can I do this in Turbo C++ 3.0? If not, I also have CodeWarrior, but it's the Learning Edition though it can create Windows Executables, but it can't do things like colors and text, since it doesn't use a standard MS-DOS (console) window. Is there any way to fix this or incorporate standard C++ into this for colors?

    Also, I need to store the names into a String or char[]. Please tell me how to do that. If I need to search a given drive, is there any pre-defined variable pointing to the user's cd-drive, or should I have then enter it.
    Last edited by macrohard; February 26th, 2003 at 06:51 PM.
  22. #12
  23. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    >> Do I heed to include <windows.h>?
    Yes you do
    >> Can I do this in Turbo C++ 3.0?
    I know Borland C++ 3.0 could compile windows executables, because I used it a long time ago. I'm not sure about Turbo C++ 3.0 (Is it the same or a different compiler?)

    >> I also have CodeWarrior, ....
    I've never used CodeWarrior, so I can't answer that question -- sorry :(.

    >> Also, I need to store the names into a String or char[].
    See my original link at the beginning of the thread. Change the declarations of TCHAR to char if your compiler doesn't know what to do with TCHARs.

    >> If I need to search a given drive, is there any pre-defined variable pointing to the user's cd-drive, or should I have then enter it.
    Couple of ways to do this. You could use the Registry functions to search the Windows registry as HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices and enumerate the keys there (i.e.)anything starting with \DosDevices\ and check the values of those keys to see if the word "CDROM" is in there. That will tell you which drive is the CD drive (probably not a good way to do it).

    A much better way is to call GetLogicalDrives() or GetLogicalDriveStrings() to get a list of logical drive letters present on the system. Then you can test what type of drive each one is by calling GetDriveType() to determine the drive type.

    If you're not confident of either method or have no clue what this is about, do yourself a big favour and buy a Windows programming book first. It'll help you much better if you understand the basics of Windows programming first.

    Hope this helps :)
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Posts
    100
    Rep Power
    12
    Thanks, two more things--

    I need to keep track of the level that these directories are in. My files are organized by album UNLESS there is more than one album per artist. Then, they are organized by artist. So, I need to see whether this is a level "1" directory (in the root drive), or a level "2" directory, such that I can check if there are any subdirectories in the given directory, then discard the regular directory.

    Also, I looked at your link at the beginning of this thread, and was wondering what would go in main() to reference this function.

    Example:
    Album: Greatest Hits I, Greatest Hits II

    Structure: Artist\Greatest Hits I, Artist\Greatest Hits II
    Function will return "Artist" as an album name, but I need to discard that.

    Second thing--

    Ideally, I could send the info gathered to CDDB. Please advise.
    Last edited by macrohard; February 27th, 2003 at 01:30 PM.
  26. #14
  27. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,642
    Rep Power
    4247
    >>So, I need to see whether this is a level "1" directory (in the root drive), or a level "2" directory,
    Plenty of ways to do this. One way would be to increment a global variable at the beginning of the function and decrement it at the end. That way you can tell how deep you are in the directory structure.

    >> what would go in main() to reference this function.
    something like ParseDirs("C:\\") or ParseDir(sDriveName); where sDriveName contains the name of the CD-drive.

    >> Ideally, I could send the info gathered to CDDB.
    Been meaning to work with CDDB myself for a long time, but never looked into it seriously. If you find out how, why don't you post your results here :)

IMN logo majestic logo threadwatch logo seochat tools logo