如何知道某文件是被复制,剪切或粘贴操作?

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

16 个解决方案

#1


读取当前剪切板的内容

#2


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等函

#3


上楼的能明确点吗
你这段代码我网上看了很多遍了

#4


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

#5


期待代码出现

#6


搞定!谢谢大家参与

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;

#7


也可以通过ShFileOperation查找

#8


学习

#9


我来学习了。

#10


引用 6 楼 h98458 的回复:
搞定!谢谢大家参与
Delphi(Pascal) code
uses
  ShellApiprocedure 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>0thenbegin
    FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);//得到文件数量for i:=0to FileNumber-1dobegin
      Fillchar(pData,Sizeof(pData),0);
      DragQueryFile(pGlobal,i,@pData,Sizeof(pData));//取得文件路径和文件名
      Memo1.Lines.Add('file:'+pData);end;end;   
  CloseClipboard;end;



这个判断不出是剪切还是复制吧?
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;

#11


多谢上楼,哈哈
正在为这个问题烦呢

#12


#10楼的不错,可以区分复制,剪切!我就不说了。

#13


修改后的完美版本:

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;

#14


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

#15


楼主如何判断粘贴呢?

#16


引用 6 楼 h98458 的回复:
搞定!谢谢大家参与
Delphi(Pascal) code
uses
  ShellApiprocedure 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>0thenbegin
    FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);//得到文件数量for i:=0to FileNumber-1dobegin
      Fillchar(pData,Sizeof(pData),0);
      DragQueryFile(pGlobal,i,@pData,Sizeof(pData));//取得文件路径和文件名
      Memo1.Lines.Add('file:'+pData);end;end;   
  CloseClipboard;end;

这个方法还不错。

#1


读取当前剪切板的内容

#2


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等函

#3


上楼的能明确点吗
你这段代码我网上看了很多遍了

#4


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

#5


期待代码出现

#6


搞定!谢谢大家参与

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;

#7


也可以通过ShFileOperation查找

#8


学习

#9


我来学习了。

#10


引用 6 楼 h98458 的回复:
搞定!谢谢大家参与
Delphi(Pascal) code
uses
  ShellApiprocedure 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>0thenbegin
    FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);//得到文件数量for i:=0to FileNumber-1dobegin
      Fillchar(pData,Sizeof(pData),0);
      DragQueryFile(pGlobal,i,@pData,Sizeof(pData));//取得文件路径和文件名
      Memo1.Lines.Add('file:'+pData);end;end;   
  CloseClipboard;end;



这个判断不出是剪切还是复制吧?
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;

#11


多谢上楼,哈哈
正在为这个问题烦呢

#12


#10楼的不错,可以区分复制,剪切!我就不说了。

#13


修改后的完美版本:

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;

#14


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

#15


楼主如何判断粘贴呢?

#16


引用 6 楼 h98458 的回复:
搞定!谢谢大家参与
Delphi(Pascal) code
uses
  ShellApiprocedure 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>0thenbegin
    FileNumber:=DragQueryFile(pGlobal,$FFFFFFFF,nil,0);//得到文件数量for i:=0to FileNumber-1dobegin
      Fillchar(pData,Sizeof(pData),0);
      DragQueryFile(pGlobal,i,@pData,Sizeof(pData));//取得文件路径和文件名
      Memo1.Lines.Add('file:'+pData);end;end;   
  CloseClipboard;end;

这个方法还不错。