Directory processing function
Programming languages: C Builder Author: Wang boating
In programming, there are often some operations for the directory. If you open the Directory dialog box, create a multi-level directory, directly delete the multi-level directory, and determine if a directory exists. This article gives the programming implementation method for these issues, and gives a detailed program code for programming enthusiasts.
First, determine if the directory exists:
FileExists in C Builder, but does not provide functions existing if the directory exists, we can use the Windows API function FindFirstFile to implement this feature. The program is implemented as follows:
Set char * DIR as a directory with judgment
BOOL EXIST; / / Final result, indicating whether the directory exists
IF (DIR [Strlen (Dir)] == '//') DIR [Strlen (Dir) -1] = '/ 0'; // Delete the last "/"
Win32_find_data wfd; // Find
Handle Hfind = FindfirstFile (Dir, & WFD);
If (hfind == invalid_handle_value) exist = false; // Nothing to find an equipped, the catalog does not exist
Else
{
If (wfd.dwfileAttributes & file_attribute_directory) // Check if the result is a directory
EXIST = true; // is a directory, the directory exists
Else
EXIST = false; // is a directory, the directory does not exist
FindClose (HFIND);
}
Second, open the directory selection dialog box to select a directory:
Most professional software put a button next to the edit box requested to enter the directory. After clicking, open a directory window, many programming enthusiasts also hope to master this method. Implement this function to call the Windows API function SHBrowseForFolder, complete declared WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder (LPBROWSEINFO lpbi), returns a pointer of type ITEMIDLIST, by calling the pointer function SHGetPathFromIDList full name of the directory can be determined choice. The pointer to the BrowseInfo structure is more complicated, and the member is as follows:
HWND HWNDOWNER; / / Have the window of the dialog, you can set it to Application-> Handle
LPCITEMIDLIST PIDLROOT; / / ITEMIDLIST type pointer, indicating which path is selected, can generally be set to null
LPSTR PSZDISPLAYNAME; // After selecting, the name of the selected directory (does not include a parent directory) is copied to this pointer point
LPCSTR lpsztitle; / / The title is displayed on the directory tree in the dialog box, which can be set according to the actual situation.
Uint ulflags; // flag, a bit complicated, generally set to bif_returnonlyfsdirs
BffCallback lpfn; // callback function, generally not, set to NULL
LPARAM LPARAM; / / The predefined dialog passes the value of the callback function Int iimage; / / with the index associated with the selected directory in the system icon collection
It can be seen that using the function shbrowseForfolder is really troublesome, and ordinary enthusiasts have a certain difficulty, and now give the full block as follows:
#include
Char selectedddir [max_path]; // final result
Browseinfo Bi; //
Char foldername [max_path]; // selected directory name, such as select C: / Windows / Font, Font
LPITEMIDLIST ITEMID; // System Sign Pointer Selected Directory
MEMSET (SELECTEDDIR, 0, MAX_PATH); // Initializing the final result
MEMSET (& BI, 0, SIZEOF (BrowseInfo); // Initializing all data
Bi.hwndowner = Application-> Handle;
bi.pszdisplayName = foldername;
bi.lpsztitle = "Please select the directory"; // change into his own hope
Bi.ulflags = Bif_Returnonlyfsdirs;
Itemid = shbrowseforfolder (& bi); // call function, open the directory selection dialog
ITEMID
{
ShgetPathFromidList (itemid, selectedddir); // Get full names in the selected directory
GlobalFree (itemid); // Returned ItemID occupies system resources, don't forget to release
}
Third, build a multi-level directory directly:
The Windows API provides a function created for CreateDirectory, but to ensure that the parent directory must exist before calling, otherwise it will fail. In fact, sometimes the multi-level catalog is useful, because when establishing a directory especially the multi-layer directory, the layer is judged to greatly increase the complexity of the program. How to implement this function? I have designed a function that can directly build a multi-level directory with a recursive method, and is hereby referred to as the reference.
Bool MakeDirectoryEx (const ANSISTRING & P) // Metropolis is intended to create a directory name, returns "true" or "false" based on the results
{
IF (p.isempty ()) Return False;
INT LEN = p.length ();
CHAR * PATH = P.c_str ();
IF (Path [LEN-1] == '//')
{
Len -;
Path [len] = '/ 0';
} // Delete the end of "/"
Ansistring Dir = path;
// Separate the father directory and its own directory name
Ansistring pent;
For (int I = len-1; i> 0; I -)
{
IF (Dir.ispathDelimiter (i))
{
Parent = dir.substring (0, i);
Break;
}
}
IF (parent.isempty ()) return false; // directory name error BOOL RET = true;
IF (Parent.Length ()> 3) // If the length is less than 3, it is expressed as the root directory of the disk.
RET = Directoryexistex (parent.c_str ()); / / Check if the parent directory exists
if (! RET) Ret = MakeDirectoryEx (PARENT); / / The parent directory does not exist, recursive calls create a parent directory
IF (re) // The parent directory exists, create a directory directly
{
Security_attributes sa;
Sa.nlength = sizeof (security_attributes);
Sa.lpsecurityDescriptor = null;
Sa.binherithandle = 0;
Ret = CreatedIRectory (Path, & SA);
}
Return Ret;
}
It can be seen that the basic method is:
First check if the parent directory exists, and the function Directoryexistex used here can be designed according to the method described earlier;
If the parent directory exists, create a directory directly, otherwise self-calling creates a parent directory.
Fourth, delete the entire directory directly:
There is a deltree command under DOS to delete the entire directory, which is a very useful feature, but unfortunately, the function RemoveDirectory provided by the Windows API can only delete the control directory, just like the RD command of DOS. Programming implementation This feature also requires recursive methods, and the basic process is:
Find all the files and directories in the directory, that is, call the API function FindFirstFile, FindNextFile (*. *)
If the file is found, it is forced to delete. The so-called forced deletion, that is, call setFileAttribute to Normal before deleting it, then call DeleteFile to delete it.
If you find a directory, you call yourself, that is, starting the recursive process.
If the directory is not found, that is, it is shown as a control directory, call RemoveDirectory to delete it directly.
The specific program code is as follows:
Bool DeletedIRectoryex (Const Ansistring & P)
{
IF (p.Islegempty () || p.Length () <4) Return false; // Parameter length must be greater than 3, that is, the root directory or blank
INT LEN = p.length ();
CHAR * PATH = P.c_str ();
Ansistring Dir = path;
IF (Path [LEN-1]! = '//') DIR = DIR '/';
Ansistring Files = DIR "*. *";
WIN32_FIND_DATA WFD;
Handle Hfind = FindFirstFile (files.c_str (), & wfd);
BOOL RET = True;
Ansistring TMP;
IF (HFIND! = INVALID_HANDLE_VALUE)
{
Bool bfind = true;
While (bfind)
{
IF (wfd.cfilename [0]! = '.') // ..
{
TMP = DIR WFD.cfilename;
IF (wfd.dwfileattributes & file_attribute_directory)
{// Remove all subdireuses
Ret = RET && deletedIRectoryex (tmp.c_str (), false);
Else
{// Delete all files
SetFileAttributes (tmp.c_str (), file_attribute_normal);
RET = RET && deletefile (tmp.c_str ());
}
}
bfind = FindNextFile (Hfind, & WFD);
}
FindClose (HFIND);
}
IF (RET) RETURN Removedirectory (PATH);
Return False;
}
Finish