学院首页>网络编程>其它编程>第七章 剪贴板和动态数据交换(一)

第七章 剪贴板和动态数据交换(一)

作者: 来源: 添加时间:2006-5-24 13:28:00

  7.1.3.1 拷贝 

  Image部件上的内容和窗体上的图形可以直接拷贝到剪贴板。图像拷贝利用Clipboard的Assign方法。

  例如: 

  Clipboard.Assign(Image1.Picture); 

  把Image1上的图像拷贝到剪贴板。 

  7.1.3.2 剪切 

  图像的剪切是首先把图像拷贝到剪贴板,而后在原位置用空白图像进行覆盖。

  下面一段程序表示了图像的剪切。  

  procedure TForm1.Cut1Click(Sender: TObject);

  var

  ARect: TRect;

  begin

  Clipboard.Assign(Image1.Picture);

  with Image.Canvas do

  begin

  CopyMode := cmWhiteness;

  ARect := Rect(0, 0, Image.Width, Image.Height);

  CopyRect(ARect, Image.Canvas, ARect);

  CopyMode := cmSrcCopy;

  end;

  end; 

  7.1.3.3 粘贴 

  从剪贴板上粘贴图像,首先检测剪贴板上的数据格式。如果格式为CF_BITMAP,则调用目标位图的Assign 方法粘贴图像。

  程序清单如下。

  procedure TForm1.PasteButtonClick(Sender: TObject);

  var

  Bitmap: TBitmap;

  begin

  if Clipboard.HasFormat(CF_BITMAP) then

  begin

  Bitmap := TBitmap.Create;

  try

  Bitmap.Assign(Clipboard);

  Image.Canvas.Draw(0, 0, Bitmap);

  finally

  Bitmap.Free;

  end;

  end;

  end; 

  try...finally为资源保护块,参第十二章。

  7.1.4 建立自己的剪贴板观察程序 

   在这一节中我们要建立一个自己的剪贴板观察程序,用来保存截获到剪贴板中的位图。

   Windows允许用户建立自己的剪贴板观察程序,并把该程序添加到一个剪贴板观察器链中。在链中,位置靠前的程序有义务把有关剪贴板的消息传递到紧随其后的观察程序。而处于链首的程序由Windows的消息循环机制直接把剪贴板消息发送过来。

   建立一个剪贴板观察程序,首先该程序必须能响应相应的Windows消息。对于那些熟悉Microsoft公司Visual Basic的读者来说,这是令他们头疼而束手无策的地方。但Delphi在这方面却有良好的表现:利用关键字message,用户可以将一个过程定义为响应特定的Windows消息。如: 

  procedure WMDrawClipboard(var Msg:TWMDrawClipboard);

  message WM_DRAWCLIPBOARD; 

   可以响应WM_DRAWCLIPBOARD消息。类TWMDrawClipboard是消息类Message 的子类。Delphi把所有的消息都重新进行了定义,使用户在使用时可以直接引用其便于记忆的数据成员,而不必再自己动手去分解消息。虽然这并不能算作是一个重大的改进,但却体现了Delphi处处为用户方便着想的特点。

   我们将要建立的程序目的是把截获到剪贴板上的位图保存下来。在本书的写作过程中,这一工作是大量存在的。虽然利用Windows工具PaintBrush(画笔),通过粘贴、保存等操作可以实现这一功能,但却存在以下一些问题:

  1.程序频繁切换影响效率,当有大量位图存在时更是如此;

  2.画笔有一个很讨厌的缺陷:当剪贴板上的位图比画笔界面的客户区大时,客户区外的位图被截断。因而往往需要根据所截获位图的大小来调整画笔客户区的大小,并重新进行粘贴。而如果开始就把画笔客户区调整到足够大,又会覆盖掉屏幕上一些有用的信息。

   为解决这些问题,我开发了下面的程序。程序启动时,以极小化方式运行。此时只要剪贴板中存入位图,则自动弹出一个对话框请求用户保存。如果用户希望查看确认,则可以双击运行程序图标,选择相应按钮,剪贴板中的位图就会显示在屏幕上。

  部件关键属性设计如下: 

  ClipSaveForm:

  Caption=‘Save Bitmap in Clipboard '

  Panel1:

  Align = ' Top '

  Image1:

  Align = ' Client '

  SaveDialog1:

  FileEditStyle = fsEdit

  FileName = '*.bmp'

  Filter = 'Bitmap Files(*.bmp)|*.bmp|Any Files(*.*)|*.*'

  InitialDir = 'c:\bmp'

  Title = 'Save Bitmap' 

   程序主窗口是TForm派生类TClipSaveForm的实例。TClipSaveForm通过定义一些私有数据成员和过程,使响应和处理Windows的相应消息成为可能。下面是TClipSaveForm的类定义: 

  type

  TClipSaveForm = class(TForm)

  SaveDialog1: TSaveDialog;

  Image1: TImage;

  Panel1: TPanel;

  Button1: TButton;

  SpeedButton1: TSpeedButton;

  SpeedButton2: TSpeedButton;

  Button2: TButton;

  procedure FormCreate(Sender: TObject);

  procedure FormDestroy(Sender: TObject);

  procedure Button1Click(Sender: TObject);

  procedure Button2Click(Sender: TObject);

  procedure SpeedButton1Click(Sender: TObject);

  procedure SpeedButton2Click(Sender: TObject);

  private

  { Private declarations }

  MyBitmap: TBitmap; { 保存截获的位图 }

  View: Boolean; { 判断是否显示 }

  NextViewerHandle: HWND; { 下一剪贴板观察器的句柄 }

  procedure WMDrawClipboard(var Msg:TWMDrawClipboard);

  message WM_DRAWCLIPBOARD;

  procedure WMChangeCBChain(var Msg:TWMChangeCBChain);

  message WM_CHANGECBCHAIN;

  { 响应Windows的剪贴板消息 }

  public

  { Public declarations }

  end;

   窗口创建时,把该窗口登录为剪贴板观察器,添加到剪贴板观察器链中,同时进行变量、部件和剪贴板的初始化。 

  procedure TClipSaveForm.FormCreate(Sender: TObject);

  begin

  View := False;

  SpeedButton2.Down := True;

  MyBitmap := TBitmap.create;

  try

  MyBitmap.Width := 0;

  MyBitmap.Height := 0 ;

  except

  Application.terminate;

  end;

  Clipboard.Clear;

  NextViewerHandle := SetClipboardViewer(Handle);

  end; 
第 2 页,共 2 页 [1] [2]
站内搜索