With the ADIR() function, you just have to be careful that you don't use it in such a way that you'll get more than 13000 files in the resulting array - or you'll get an error.
ADIR() returns an array, and arrays are limited to 65000 elements. Since the array has 5 columns (at least in VFP 7), you are limited to 65000/5 rows = 13000 files before the code will blow up.
You could use the SYS(2000) function to do wildcard searches.
But lately, I've found myself using Windows Scripting Host objects. If you get a Folder object from a FileSystemObject, then loop through the Files collection in the Folder object, you can do all sorts of interesting things, since the file object has lots of properties/methods.
Here's a sample of what I'm talking about:
loFS=CREATEOBJECT("scripting.filesystemobject"

lcFolder = GETDIR()
IF DIRECTORY(lcFolder)
loFolder = loFS.GetFolder(lcFolder)
FOR EACH loFile IN loFolder.Files
IF UPPER(JUSTEXT(loFile.Name)) == "PRG"
* Here is a .PRG file in the folder.
?loFile.Name
ENDIF
ENDFOR
ENDIF
I've encountered strange OLE errors trying to access the Files collection of the Folder directly (passing any sort of index), but the FOR EACH loop seems to work fine, and it gives you a quick and easy way to use the file objects.