One nice feature in the Windows shell is the Recycle Bin. You can manipulate the Recycle Bin in your code by using functions contained in SHELL32.DLL. You can send deleted files to the Recycle Bin and, if you have the right version of SHELL32.DLL, you can empty the Recycle Bin as well.
Listing A shows the header for a unit that contains the functions presented in this article. Listing B shows the source code for three functions that you can use to manipulate the Recycle Bin.
The shell API contains a very powerful function called SHFileOperation(). Using this function, you can copy, move, rename, or delete a list of files and directories. SHFileOperation() can also ask for user confirmation and display animations for operations that take a long time. SHFileOperation() is supported by all versions of SHELL32.DLL.
I have wrapped SHFileOperation() with a function called DeleteFiles(). This function takes a String argument, filespec, which contains the name of a file. The filespec parameter can include wildcard characters to delete a group of files. DeleteFiles() also takes a bool argument, allowUndo. If allowUndo is true, the files are removed from their original location and sent to the recycle bin. If allowUndo is false (the default) the files are permanently deleted.
Versions of SHELL32.DLL greater than or equal to 4.71 contain two functions called SHQueryRecycleBin() and SHEmptyRecycleBin().(In the last issue, you learned how to determine the version of SHELL32.DLL using the GetDLLVersion() function.) You can use these two functions to empty the Recycle Bin in your programs.
SHQueryRecycleBin() returns information about the Recycle Bin, including how many files are in it. The CanEmptyRecycleBin() function is a simple wrapper for SHQueryRecycleBin(). If the Recycle Bin is empty or if SHQueryRecycleBin() is not available, CanEmptyRecycleBin() returns false, otherwise it returns true.
The EmptyRecycleBin() function wraps SHEmptyRecycleBin(). It takes a DWORD argument, flags. The values in Table A can be used with the flags parameter. The default is SHERB_SILENT.
Table A: Flags for the EmptyRecycleBin() function.
|
SHERB_NOCONFIRMATION |
Do not display a confirmation
dialog before emptying the Recycle Bin. |
|
SHERB_NOPROGRESSUI |
Do not display progress while
emptying the Recycle Bin. |
|
SHERB_NOSOUND |
Do not play a sound when the
Recycle Bin has been emptied. |
|
SHERB_SILENT |
A combination of all the
flags above. |
EmptyRecycleBin() returns true if SHEmptyRecycleBin() is available and the Recycle Bin is successfully emptied. Otherwise, EmptyRecycleBin() returns false.
The example program for this article creates three dummy files and then uses DeleteFiles() to delete the files to the Recycle Bin. The program uses CanEmptyRecycleBin() to enable or disable a button that, when enabled, uses EmptyRecycleBin() to empty the Recycle Bin. You can download the example from the Bridges Publishing Web site.
Listing A: RecBin.h
#ifndef RecycleH
#define RecycleH
#include <shellapi.h>
bool DeleteFiles(
String filespec, bool allowUndo = false);
const DWORD SHERB_SILENT = SHERB_NOCONFIRMATION |
SHERB_NOPROGRESSUI | SHERB_NOSOUND;
bool EmptyRecycleBin(DWORD flags = SHERB_SILENT);
bool CanEmptyRecycleBin();
#endif // RecycleH
Listing B: RecBin.cpp
#include <vcl\vcl.h>
#pragma hdrstop
#include <shellapi.h>
#include "DLLVersion.h"
#include "RecBin.h"
bool DeleteFiles(String filespec, bool allowUndo)
{
SHFILEOPSTRUCT shop;
ZeroMemory(&shop, sizeof(shop));
shop.wFunc = FO_DELETE;
shop.pFrom = filespec.c_str();
shop.fFlags =
FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
if (allowUndo) shop.fFlags |= FOF_ALLOWUNDO;
return (SHFileOperation(&shop) == 0);
}
bool EmptyRecycleBin(DWORD flags)
{
if (GetDLLVersion("shell32.dll") <
PackDLLVersion(4, 71))
return(false);
return (SHEmptyRecycleBin(
Application->MainForm->Handle,
0, flags) == S_OK);
}
bool CanEmptyRecycleBin()
{
if (GetDLLVersion("shell32.dll") <
PackDLLVersion(4, 71))
return(false);
SHQUERYRBINFO info;
ZeroMemory(&info, sizeof(info));
info.cbSize = sizeof(info);
SHQueryRecycleBin(0, &info);
return (info.i64NumItems > 0);
}
#pragma package(smart_init)