许多提供剪切、复制和粘贴功能的应用程序都有一个共同特点,那就是:工具栏上表示这三个功能的按钮会随着剪贴板的变化而变化,具体来说,粘贴按钮只有在剪贴板上有内容时才处于使能状态,而当剪贴板空时则变灰,也就是不能使用;相似地,剪切、复制按钮也只有在当前有文本或位图被选择时才有效。那么,这是怎么实现的呢?笔者曾经想在Delphi4.0中放置一个Timer控件,在其OnTimer事件中加入侦测剪贴板变化的代码,但最后放弃了,原因是Timer控件比较消耗系统资源,得不偿失,而且笔者也相信,那些应用程序的源代码也不是这么做的。其实,这个问题的关键在于怎么样响应Windows消息,这里就是响应剪贴板消息。Delphi体贴地将所有的Windows消息都重新定义,令我们可以方便地通过message关键字访问这些消息而不用理会恼人的API。下面,就用一个实例说明Delphi是怎么做的。
  程序需要一个ToolBar控件,在其上建立三个按钮;一个ImageList控件,为其加入三个小位图,分别表示剪切、复制和粘贴,将ImageList 赋予ToolBar的images属性;一个Memo控件,将其Lines属性置空。以下是程序清单:
  unit Unit1;
  interface
  uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,ClipBrd, ComCtrls, ImgList, ToolWin;
  type
   TForm1 = class(Tform)
   ToolBar1: TToolBar;
   ImageList1: TImageList;
   ToolButton1: TToolButton;
   ToolButton2: TToolButton;
   ToolButton3: TToolButton;
   Memo1: Tmemo;
   procedure FormCreate(Sender: Tobject);
   procedure FormDestroy(Sender: Tobject);
   procedure Memo1MouseUp(Sender: Tobject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
   procedure ToolButton1Click(Sender: Tobject);
   procedure ToolButton2Click(Sender: Tobject);
   procedure ToolButton3Click(Sender: Tobject);
   private
   { Private declarations }
   viewhandle:HWND;
   procedure Change(var msg:TWMdrawclipboard);
   message wm_drawclipboard;
   public
   { Public declarations }
   end;
  var
   Form1: TForm1;
  implementation
  {$R *.DFM}
  procedure TForm1.FormCreate(Sender: Tobject);
  begin
  Memo1.Align:=alClient;
  ToolBar1.Flat:=True;
  viewhandle:=SetClipboardviewer(Handle);
  ToolButton1.Enabled:=False;
  ToolButton2.Enabled:=False; 
  end;
  procedure TForm1.FormDestroy(Sender: Tobject);
  begin
  ChangeClipboardChain(Handle,viewhandle);
  end;
  procedure TForm1.Memo1MouseUp(Sender: Tobject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
  begin
  if Memo1.SelText<>`` then
   begin
   ToolButton1.Enabled:=True;
   ToolButton2.Enabled:=True;
   end
  else
   begin
   ToolButton1.Enabled:=False;
   ToolButton2.Enabled:=False;
   end
  end;
  procedure TForm1.ToolButton1Click(Sender: Tobject);
  begin
   Memo1.CutToClipboard;
  end;
  procedure TForm1.ToolButton2Click(Sender: Tobject);
  begin
   Memo1.CopyToClipboard;
  end;
  procedure TForm1.ToolButton3Click(Sender: Tobject);
  begin
   Memo1.PasteFromClipboard;
  end;
  procedure TForm1.Change(var msg:TWMdrawclipboard);
  begin
  ToolButton3.Enabled:=Clipboard.Hasformat(cf_text)
  end;
  end.
  注意程序中的关键字:message,它使Change过程可以响应剪贴板消息,
即剪贴板中有文本内容时粘贴按钮有效,反之无效;而剪切、复制按钮的状
态在Memo1的MouseUp事件中响应。程序中的SetClipboardviewer函数用来登
陆剪贴板,ChangeClipboardChain函数用来退出剪贴板。另外还有一点要说
明的是:由于代码中有剪贴板类的操作,因此Uses子句中要加上ClipBrd。

解决方案 »

  1.   

    设一个数组或队列,记录下用户的操作看一下Word里的撤销操作的下拉小箭头里的内容,如“键入XXX”,“删除XXX”等
    当然还要记录事件发生的位置。有了记录,就可以执行撤销了。
      

  2.   

    楼上的,可不可以给点例子,我菜得很。
    数组应该怎样设,我记下的内容以什么为单位。
    WINDOWS系统自带的NOTEPAD可以做到:当你一次粘贴很多内容,撤消可以删除全部粘贴内容。还有定位。
            请指点.........
      

  3.   

    www.xmflyfish.com/awind/aspcode.asp 第三个就是一个记事本源程序,好象有你要的