There's a lot of tips on the web about recycling files. Most of them are not working properly. I've found that the same piece of code sometimes work and sometimes not. This tends to be a bit frustating. Well, I think at last I've got an answer to the problem:
MicroSoft has a documentation correction about the pFrom member in the TShFileOpStruct used in the recycling routine. It says that for multiple files to be recycled, each file is to be separated by a NULL (#0) character, and the whole thing terminated by double NULLs. You need the double NULLs whether or not you are passing multiple filenames. Sometimes it will work correctly without them, but often not. That's because sometimes you get lucky and the memory following the end of your string has a NULL there.
There are some other quirks you should be aware of, too: Give the complete file path for every file specified. Do not rely on the current directory, even if you change to it right before the call. The SHFileOperation API is not "smart" enough to use the current directory if one is not given for undo information. So, even if you give the FOF_ALLOWUNDO flag, it will not move deleted files to the recycle bin because it doesn't know what path they came from, and thus couldn't restore them to their original location from the recycle bin. It will simply delete the file from the current directory.
An example of how to recycle a file, and be successful, would be:
function RecycleFile(FileName: string): Boolean;
var FOS: TSHFileOpStruct;
begin
FillChar(FOS, SizeOf(FOS), 0);
with FOS do
begin
wFunc:= FO_DELETE;
pFrom:= PChar(FileName + #0#0);
fFlags:= FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_NOERRORUI;
end;
Result:= (ShFileOperation(FOS) <> 0);
end;