Directory processing function

zhaozj2021-02-08  270

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 // must contain the header file

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

转载请注明原文地址:https://www.9cbs.com/read-1044.html

New Post(0)