比如说有C:\abc这个文件夹,里边有1.txt,2.txt两文件
当我对1.txt进行复制或剪切操作时,我要知道文件1.txt被复制或剪切了
请问如何实现呢?

解决方案 »

  1.   

    Windows使用剪贴板观察器和观察链。剪贴板观察器是一个显示剪贴板当前内容的窗口。     
        
      通常它应该至少能显示三种普通格式的内容:文字CF_TEXT、位图CF_BITMAP、元文件CF_MET     
        
      AFILEPICT。剪贴板观察链是一系列相互独立的剪贴板观察窗口,它们都能够接受当前发送     
        
      到剪贴板的内容。我们大致按照以下步骤在窗口中处理有关剪贴板的内容。     
        
            
        
          首先,使用SetClipboardViewer(HWND)函数向剪贴板观察链中加入一个观察窗口。当剪     
        
      贴板的内容发生变化时,该窗口会接收到一个WM_DRAWCLIPBOARD消息。该函数需要传递的参     
        
      数是观察窗口的句柄。返回值也是一个窗口句柄类型,标识了将要加入的下一个窗口。     
        
            
        
          然后,响应WM_DRAWCLIPBOARD消息处理剪贴板内容的变化。     
        
            
        
          最后,在程序退出或关闭时需要调用ChangeClipboardChain函数来将自己从观察链中删除     
        
      。然后调用SendMessage函数把这些消息传递到观察链中的下一个观察窗口。函数ChangeCli     
        
      pboardChain原型如下:     
        
            
        
      BOOL   ChangeClipboardChain(     
        
      HWND   hWndRemove,         //将要删除的窗口的句柄     
        
      HWND   hWndNewNext           //观察链中下一个窗口的句柄     
        
            );     
        
            
        
          Delphi的clipbrd.pas单元中定义了一个类TClipboard,它封装了Windows剪贴板,简化了     
        
      大量复杂的处理过程。我们在程序中可以直接调用全局函数Clipboard,该函数用于返回TCl     
        
      ipboard对象实例,使用这个实例对剪贴板进行剪切、复制和粘贴等操作。下面是TClipboar     
        
      d对象的几个常用的方法和属性的简单介绍。     
        
            
        
      方法:     
        
                Assign:将指定的对象放入剪贴板中。     
        
          Open:打开剪贴板,防止其他程序改写剪贴板。在向剪贴板加入多项数据时尤其有用。     
        
          Close:关闭剪贴板。应该与打开剪贴板成对使用。     
        
          Clear:清空剪贴板。     
        
          GetAsHandle:返回剪贴板中指定格式数据的句柄。使用前必须打开剪贴板。     
        
          GetComponent:返回剪贴板中的一个控件。Delphi自己使用得多。     
        
          HasFormat:查询剪贴板中是否有指定格式的内容。     
        
      属性:     
        
          AsText:用于读写剪贴板文字内容。     
        
          FormatCount:读剪贴板中数据格式的种数。     
        
          Formats:返回剪贴板中各种格式的列表。     
        
            
        
          此外,Delphi中的许多控件中也封装了有关剪贴板处理的操作。下面的一个处理剪贴板的     
        
      简单例子,只是将剪贴板的文字内容显示为窗口标题。     
        
            
        
      unit   Unit1;     
        
            
        
      interface     
        
          uses   Windows,   Messages,   SysUtils,   Classes,Graphics,   Controls,   Forms,   Dialogs,C     
        
      lipbrd;//加入clipbrd单元     
        
            
        
      type     
        
          TForm1   =   class(TForm)     
        
              procedure   FormCreate(Sender:   TObject);     
        
              procedure   FormClose(Sender:   TObject;   var   Action:   TCloseAction);     
        
          private     
        
              {   Private   declarations   }     
        
          public     
        
              NextClipHwnd:HWND;//观察链中下一个窗口句柄     
        
              procedure   WMDrawClipBoard(var   AMessage:TMessage);   message   WM_DRAWCLIPBOARD;/     
        
      /处理WM_DRAWCLIPBOARD消息过程     
        
          end;     
        
            
        
      var     
        
          Form1:   TForm1;     
        
            
        
      implementation     
        
            
        
      {$R   *.DFM}     
        
            
        
      {   TForm1   }     
        
            
        
      procedure   TForm1.WMDrawClipBoard(var   AMessage:   TMessage);     
        
      begin     
        
            //将WM_DRAWCLIPBOARD消息传递到下一个观察链中的窗口     
        
          SendMessage(NextClipHwnd,AMessage.Msg,AMessage.WParam,AMessage.LParam);     
        
            
        
          //查询剪贴板中特定格式的数据内容     
        
          if   (Clipboard.HasFormat(CF_TEXT)   or     Clipboard.HasFormat(CF_OEMTEXT))   then     
        
          begin     
        
              //处理剪贴板中内容     
        
              Caption:=Clipboard.asText;     
        
          end;     
        
      end;     
        
            
        
      procedure   TForm1.FormCreate(Sender:   TObject);     
        
      begin     
        
          //获得观察链中下一个窗口句柄     
        
          NextClipHwnd:=SetClipBoardViewer(Handle);     
        
      end;     
        
            
        
      procedure   TForm1.FormClose(Sender:   TObject;   var   Action:   TCloseAction);     
        
      begin     
        
          //从观察链中删除本观察窗口     
        
          ChangeClipboardChain(Handle,NextClipHwnd);     
        
            
        
          //将WM_DRAWCLIPBOARD消息传递到下一个观察链中的窗口     
        
          SendMessage(NextClipHwnd,WM_CHANGECBCHAIN,Handle,NextClipHwnd);     
        
      end;     
        
            
        
      end.     
        
            
        
          需要注意的是,在处理剪贴板内容变化的消息WM_DRAWCLIPBOARD的过程和关闭窗口事件中     
        
      使用函数sendmessage把WM_DRAWCLIPBOARD或WM_CHANGECBCHAIN消息传递到观察链中的下一     
        
      个窗口是必要的,否则有可能其他窗口不能获得类似消息。另外,在使用网络蚂蚁时笔者曾     
        
      经碰到不能设置剪贴板格式的情况,在此提醒读者注意检查RegisterClipboardFormat等函
      

  2.   

    可以利用HOOK 对文件的操作进行监视
    http://blog.chinaunix.net/u1/35278/showart_303863.html
    这个文章对你有用
      

  3.   

    搞定!谢谢大家参与uses
      ShellApi
    procedure TForm1.Button2Click(Sender: TObject);
    var   
      pGlobal     :   Thandle;   
      FileNumber,i:Integer;   
      pData:   array[0..MAX_PATH]   of   Char;
      sMD5:string;
    begin
      OpenClipboard(self.Handle);
      pGlobal:=GetClipboardData(CF_HDROP);   //获取剪贴板的文件数据
      if pGlobal>0 then
      begin
        FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);     //得到文件数量
        for i:=0 to FileNumber-1 do
        begin
          Fillchar(pData,Sizeof(pData),0);
          DragQueryFile(pGlobal,i,@pData,Sizeof(pData));       //取得文件路径和文件名
          Memo1.Lines.Add('file:'+pData);
        end;
      end;   
      CloseClipboard; 
    end;
      

  4.   

    这个判断不出是剪切还是复制吧?
    var
        cDropEffect: UINT; // 注册类别
        hDropEffect: HGLOBAL; // 操作类型
        pDropEffect: PDWORD;begin
    if Clipboard.HasFormat(CF_HDROP) then
                begin
                    Clipboard.Open;
        //从剪贴板取回文件名称
                    f := Clipboard.GetAsHandle(CF_HDROP);
                    if f <> 0 then
                    begin
                        numFiles := DragQueryFile(f, $FFFFFFFF, nil, 0);
                        for i := 0 to numFiles - 1 do
                        begin
                            DragQueryFile(f, i, FFileName, SizeOf(FFileName));
                            s := s + FFileName + #0;
                        end;
                    end;
                    cDropEffect := RegisterClipboardFormat('Preferred DropEffect');
                    hDropEffect := getClipboardData(cDropEffect);
                    pDropEffect := GlobalLock(hDropEffect);
                    GlobalUnlock(hDropEffect);
                    Clipboard.Close;                if pDropEffect^ = DROPEFFECT_MOVE then
                        showmessage('是剪切');
    else showmessage('是复制')
                end;
    end;
      

  5.   

    修改后的完美版本:uses
      ShellApi
    procedure TForm1.Button2Click(Sender: TObject);
    var   
      pGlobal     :   Thandle;   
      FileNumber,i:Integer;   
      pData:   array[0..MAX_PATH]   of   Char;
      sMD5:string;  cDropEffect: UINT; //注册类别
      hDropEffect: HGLOBAL; //操作类型
      pDropEffect: PDWORD;
      sCutOrCopy:string;
    begin
      OpenClipboard(self.Handle);
      pGlobal:=GetClipboardData(CF_HDROP);   //获取剪贴板的文件数据
      if pGlobal>0 then
      begin
        FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);     //得到文件数量
        for i:=0 to FileNumber-1 do
        begin
          Fillchar(pData,Sizeof(pData),0);
          DragQueryFile(pGlobal,i,@pData,Sizeof(pData));       //取得文件路径和文件名       cDropEffect := RegisterClipboardFormat('Preferred DropEffect');
          hDropEffect := getClipboardData(cDropEffect);
          pDropEffect := GlobalLock(hDropEffect);
          GlobalUnlock(hDropEffect);
          if pDropEffect^ = DROPEFFECT_MOVE then
           sCutOrCopy:='Cut'
          else
           sCutOrCopy:='Copy';
          Memo1.Lines.Add(pData+'***'+sCutOrCopy);
        end;
      end;   
      CloseClipboard; 
    end;
      

  6.   

    //还要定义两个常量
    const   
      DROPEFFECT_COPY=1;
      DROPEFFECT_MOVE=2;