tags:

views:

318

answers:

2

I want to use IFileOperation CopyItem to copy a file from a directory to another directory is there a simple example in delphi 7?

+1  A: 

At the time of my original answer, the first hit on the TFileOperation CopyItem Delphi search is a nice blog post by Bruno Martins Stuani on using IFileOperation and its' CopyItem method.
The post includes Delphi sample code.

Edit: Starting with Delphi 2010, the IFileOperation interface is defined in the ShlObj unit.
It depends on quite a few other things in that unit, so it is not a quick "copy-paste" here (besides the fact that the unit is copyrighted).

--jeroen

Jeroen Pluimers
The blog post is about intercepting fileoperations, but nowhere is explained how to use `IFileOperation.CopyItem`?
The_Fox
Actually, the first hit on your Google Search points to this page, where there is an instruction to jump to the first link of another page that points to a page with an instruction to jump to the first link of ano..[STACKOVERFLOW]
Wouter van Nifterick
@Wouter: Since Delphi 7 does not include the translation of IFileOperation, I understood `use` as `have a Delphi translation of the IFileOperation interface`. Bruno provided just that. @The_Fox: at the time of my writing it was; StackOverflow has great SEO, so usually it ends up in google searches high very soon. That's why I posted the link to Bruno's posting. I'm glad you provided an even more extensive answer and gave you an upvote.--jeroen
Jeroen Pluimers
@Jeroen, I understood the question as `how to do this in Delphi` but missed the version part. The poster must indeed have a translation of the IFileOperation interface. Unfortunatly the blog post only contains a translation of IShellItem, not of IFileOperation.
The_Fox
the blog also uses madecodehook's unit and the unit is not free,I think calling the api is more simple, while delphi units are open source so the IFileOperation defination can be extract from the delphi 2010 Unit
roza
@Jeroen: quite some of those can be copied from the respective FPC sources. I haven't gotten around to IFileOperation yet, but e.g. IFiledialog is ported. See also http://stackoverflow.com/questions/1894318/delphi-7-and-vista-windows-7-common-dialogs-events-do-not-work
Marco van de Voort
@Marco: good to hear you worked so hard. +1 if I could :-)
Jeroen Pluimers
+3  A: 

I found the MSDN documentation and it included an example. Here is the example translated to Delphi:

uses ActiveX, ComObj, ShlObj;

function TForm1.CopyItem(const aSrcItem, aDest, aNewName: string): HRESULT;
const
  CLSID_FileOp: TGUID = '{3ad05575-8857-4850-9277-11b85bdb8e09}';
var
  lFileOperation: IFileOperation;
  psiFrom: IShellItem;
  psiTo: IShellItem;
begin
  //
  // Initialize COM as STA.
  //
  Result := CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
  if Succeeded(Result) then
  begin

    //
    // Create the IFileOperation interface
    //
    Result := CoCreateInstance(CLSID_FileOp, nil, CLSCTX_ALL, IFileOperation,
                          lFileOperation);
    if Succeeded(Result) then
    begin
      //
      // Set the operation flags. Turn off all UI from being shown to the
      // user during the operation. This includes error, confirmation,
      // and progress dialogs.
      //
      Result := lFileOperation.SetOperationFlags(FOF_NO_UI);
      if Succeeded(Result) then
      begin
        //
        // Create an IShellItem from the supplied source path.
        //
        Result := SHCreateItemFromParsingName(aSrcItem,
                                         nil,
                                         IShellItem, psiFrom);
        if Succeeded(Result) then
        begin
          if aDest <> '' then
          begin
            //
            // Create an IShellItem from the supplied
            // destination path.
            //
            Result := SHCreateItemFromParsingName(aDest,
                                             nil,
                                             IShellItem, psiTo);
          end;

          if Succeeded(Result) then
          begin
            //
            // Add the operation
            //
            Result := lFileOperation.CopyItem(psiFrom, psiTo, aNewName, nil);

            psiTo := nil;
          end;

          psiFrom := nil;
        end;

        if Succeeded(Result) then
        begin
          //
          // Perform the operation to copy the file.
          //
          Result := lFileOperation.PerformOperations;
        end;
      end;

      //
      // Release the IFileOperation interface.
      //
      lFileOperation := nil;
    end;

    CoUninitialize;
  end;
end;

Disclaimer: IFileOperation.CopyItem is available from Windows Vista and higher. So the above example will only work with Delphi 2010 (and 2009?). Since I am on Delphi 7 I cannot compile this because I am missing the latest version of unit ShlObj. Fortunatly using COM from Delphi is pretty easy, so converting the example wasn't a big deal. I googled the CLSID for IFileOperation, so I don't know if it is the right one.

If you really want this to work with Delphi 7, you must have a definition of IFileOperation. The link provided by Jeroen has a definition of IShellItem but not for IFileOperation. If you know someone with a Delphi 2010 version, you could ask him for ShlObj.pas (but it is copyrighted, so you have to translate Shobjidl.h yourself or wait for someone else to do it, you could check the JEDI project).

When all this seems very complicated, try the Windows Api call, CopyFile.

The_Fox
That's a pretty good translation, but you don't need to nil the interfaces. Interface references are ref-counted, and the Delphi compiler will release them automatically when they go out of scope at the end of the function.
Mason Wheeler
@Mason Wheeler: I know, but I just translated the MSDN example. So where the MSDN example called Release, I nilled them. Just to show how you would do it in Delphi, although it is redundant.
The_Fox