当前位置:首页 > 网络编程 > 软件语言 > DELPHI > 剪贴板和动态数据交换(一)

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

点击次数:45 次 发布日期:2008-11-09 08:43:09 作者:源代码网
源代码网推荐
广告载入中
应用程序间的数据交换是象Windows 这样的多任务环境的重要特性。作为一种基于Windows的开发工具,Delphi支持如下四种数据交换方式:剪贴板、动态数据交换 ( DDE)、对象联接与嵌入(OLE)以及动态联接库(DLLs)。这中间前三种方式最为常用,OLE功能最为强大,DDE次之。而剪贴板使用最为方便。在本章,我们只讨论剪贴板和动态数据交换。利用OLE实现数据交换见下一章,利用动态联接库(DLLs)进行数据交换将在第十章中介绍。  

7.1 剪贴板及其应用 

源代码网整理以下 本质上,剪贴板只是一个全局内存块。当一个应用程序将数据传送给剪贴板后,通过修改内存块分配标志,把相关内存块的所有权从应用程序移交给Windows自身。其它应用程序可以通过一个句柄找到这个内存块,从而能够从内存块中读取数据。这样就实现了数据在不同应用程序间的传输。   软件开发网 www.mscto.com

源代码网整理以下 剪贴板虽然功能较为简单,且不能实现实时传输,但却是更为复杂的DDE和OLE的基础。对于一些只是偶尔需要使用其它应用程序数据的程序来说,使用剪贴板不失为一种方便、快捷的方式。

源代码网整理以下 Delphi把剪贴板的大部分功能封装到一个TClipboard类中,同时把使用频度最高的文本传输功能(包括DBImage的图像传输功能)置入相应部件作为部件的方法,从而使用户可以十分方便地使用剪贴板进行编程。 

源代码网整理以下7.1.1 使用剪贴板传输文本 

源代码网整理以下剪贴板传输文本主要是应用如下的三个方法:CopyToClipboard、CutToClipboard 和PasteFromClipboard。包含这些方法的部件如下表所示。 

源代码网整理以下   表7.1 包含剪贴板方法的部件

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━

源代码网整理以下方 法 部 件

源代码网整理以下——————————————————————————— 软件开发网 www.mscto.com

软件开发网 www.mscto.com

源代码网整理以下TDBEdit TDBMemo 软件开发网 www.mscto.com

源代码网整理以下TDBImage

源代码网整理以下CopyToClipboard TEdit TMemo TMaskEdit

源代码网整理以下TOLEContainer

源代码网整理以下TDDEServerItem

源代码网整理以下———————————————————————————

源代码网整理以下TDBEdit TDBMemo

源代码网整理以下CutToClipboard TDBImage

源代码网整理以下TEdit TMemo TMaskEdit

源代码网整理以下———————————————————————————

源代码网整理以下TDBEdit TDBMemo

源代码网整理以下PasteFromClipboard TDBImage

源代码网整理以下TEdit TMemo TMaskEdit

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

源代码网整理以下 除TDBImage外,其余全是有关文本的控件。

软件开发网 www.mscto.com

源代码网整理以下 在把文本传输到剪贴板之前,文本必须被选中。

源代码网整理以下 若选TMaskEdit的AutoSelect属性为True,则当MaskEdit获得输入焦点时文本自动被选中;若选TEdit、TMemo的HideSelection属性为True,则失去焦点时,文本选中状态自动隐藏,重新获得焦点时再显示。

源代码网整理以下下面的语句把MaskEdit中选中的文本剪切到剪贴板: 

源代码网整理以下MaskEdit .CutToClipboard; 

源代码网整理以下下面的语句把剪贴板中的文本粘贴到Memo的当前光标处: 

源代码网整理以下Memo.PasteFromClipboard; 

源代码网整理以下利用剪贴板类也可以实现文本的传输,见(7.1.2)中的介绍。 

源代码网整理以下7.1.2 剪贴板类 

源代码网整理以下 为方便剪贴板的操作,Delphi在Clipbrd库单元中定义了一个TClipboard类,并且预定义了一个变量Clipboard作为类TClipboard的实例,从而使用户在绝大多数场合不必自己去定义一个TClipboard的实例。

源代码网整理以下 利用剪贴板类可以进行文本、图像和部件的传输,剪贴板类为实现这些方法提供了相应的属性和方法。表7.2、表7.3列出了TClipboard属性和方法的意义。  

源代码网整理以下表 7.2 TClipboard的属性

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━

源代码网整理以下属 性 意 义

源代码网整理以下───────────────────────────

源代码网整理以下AsText 保存剪贴板的文本,只有运行时才可设置

源代码网整理以下FormatCount 可用剪贴板格式的数目

源代码网整理以下Formats 可用剪贴板格式链

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

源代码网整理以下   表 7.3 TClipboard的方法

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

源代码网整理以下方 法 参 数 意 义

源代码网整理以下─────────────────────────────────────

源代码网整理以下Clear 无 清除剪贴板的内容

源代码网整理以下Assign Source:TPersistent 把Source参数指定的对象拷贝到剪贴板,常

源代码网整理以下用于图形、图像对象

源代码网整理以下Open 无打开剪贴板,阻止其它应用程序改变它的内容

源代码网整理以下Close 无 关闭打开的剪贴板 软件开发网 www.mscto.com

源代码网整理以下SetComponent Source:TPersistent 把部件拷贝到剪贴板

源代码网整理以下GetComponent Owner 从剪贴板取回一个部件并放置

源代码网整理以下Parent :TPersistent

源代码网整理以下SetAsHandle Format:Word 把指定格式数据的句柄交给剪贴板

源代码网整理以下返回类型:THandle

源代码网整理以下GetAsHandle Format:Word 返回剪贴板指定格式数据的句柄

源代码网整理以下返回类型:THandle

源代码网整理以下HasFormat Format:Word 判断剪贴板是否拥有给定的格式

源代码网整理以下返回类型:Boolean

源代码网整理以下SetTextBuf Buffer:PChar 设置剪贴板的文本内容

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

源代码网整理以下  剪贴板中可能的数据格式如下表。 

源代码网整理以下表 7.4 剪贴板数据格式及其意义

软件开发网 www.mscto.com

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

源代码网整理以下数据格式 意 义

源代码网整理以下──────────────────────────────

软件开发网 www.mscto.com

源代码网整理以下CF_TEXT 文本。每行以CF_LF结束,nil标志文本结束

源代码网整理以下CF_BITMAP Windows位图

源代码网整理以下CF_METAFILE Windows元文件

源代码网整理以下CF_PICTURE TPicture类型的对象

源代码网整理以下CF_OBJECT 任何TPersistent类型的对象 软件开发网 www.mscto.com

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

源代码网整理以下利用TClipboard实现文本的传输使用AsText属性和SetTextBuf方法。

源代码网整理以下AsText属性为非控件部件的剪贴板操作提供了方便。如: 

源代码网整理以下Clipboard. AsText := Form1.Caption ; 

源代码网整理以下把Form1的标题拷贝到剪贴板。  软件开发网 www.mscto.com

源代码网整理以下Label1.Caption := Clipboard.AsText; 

源代码网整理以下把剪贴板中的文本写入Label1。

源代码网整理以下SetTextBuf用于把超过255个字符的字符串拷入剪贴板。 

源代码网整理以下7.1.3 利用剪贴板传输图像 

源代码网整理以下7.1.3.1 拷贝 

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

源代码网整理以下例如: 

源代码网整理以下Clipboard.Assign(Image1.Picture); 

源代码网整理以下把Image1上的图像拷贝到剪贴板。 

源代码网整理以下7.1.3.2 剪切 

源代码网整理以下图像的剪切是首先把图像拷贝到剪贴板,而后在原位置用空白图像进行覆盖。

源代码网整理以下下面一段程序表示了图像的剪切。  

源代码网整理以下procedure TForm1.Cut1Click(Sender: TObject);

源代码网整理以下var

源代码网整理以下ARect: TRect;

软件开发网 www.mscto.com

源代码网整理以下begin

源代码网整理以下Clipboard.Assign(Image1.Picture);

源代码网整理以下with Image.Canvas do

源代码网整理以下begin

源代码网整理以下CopyMode := cmWhiteness;

源代码网整理以下ARect := Rect(0, 0, Image.Width, Image.Height);

软件开发网 www.mscto.com

源代码网整理以下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; 

软件开发网 www.mscto.com

源代码网整理以下 可以响应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:mp"

源代码网整理以下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);

软件开发网 www.mscto.com

源代码网整理以下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);

软件开发网 www.mscto.com

源代码网整理以下message WM_CHANGECBCHAIN;

源代码网整理以下{ 响应Windows的剪贴板消息 }

源代码网整理以下public

源代码网整理以下{ Public declarations }

源代码网整理以下end;

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

源代码网整理以下procedure TClipSaveForm.FormCreate(Sender: TObject);

源代码网整理以下begin 软件开发网 www.mscto.com

源代码网整理以下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; 

源代码网整理以下窗口关闭时,退出剪贴板观察器链,并释放内存: 

源代码网整理以下procedure TClipSaveForm.FormDestroy(Sender: TObject); 软件开发网 www.mscto.com

源代码网整理以下begin

源代码网整理以下ChangeClipboardChain(Handle,NextViewerHandle);

源代码网整理以下MyBitmap.Free;

源代码网整理以下end; 

源代码网整理以下在以上两段程序中用到的两个Windows API函数SetClipboardViewer和ChangeClipboardChain分别用于登录和退出剪贴板观察器链。

源代码网整理以下程序保存位图的功能是在消息响应过程WMDrawClipboard中实现的。该过程在剪贴板内容有变化时被调用。 

源代码网整理以下procedure TClipSaveForm.WMDrawClipboard(var Msg: TWMDrawClipboard);

源代码网整理以下var 软件开发网 www.mscto.com

源代码网整理以下FileName: String;

源代码网整理以下begin

软件开发网 www.mscto.com

源代码网整理以下If NextViewerHandle <> 0 then[page]

源代码网整理以下SendMessage(NextViewerHandle,msg.Msg,0,0);

源代码网整理以下If ClipBoard.HasFormat(CF_BITMAP) then

源代码网整理以下begin

源代码网整理以下MyBitmap.Assign(Clipboard);

源代码网整理以下If SaveDialog1.Execute then

源代码网整理以下begin

源代码网整理以下FileName := SaveDialog1.FileName;

源代码网整理以下MyBitmap.SaveToFile(FileName);

源代码网整理以下end; 软件开发网 www.mscto.com

源代码网整理以下If View then

源代码网整理以下begin

源代码网整理以下WindowState := wsNormal;

源代码网整理以下Image1.Picture.Bitmap := MyBitmap;

源代码网整理以下end;

源代码网整理以下end;

源代码网整理以下Msg.Result := 0;

源代码网整理以下end; 

源代码网整理以下 程序首先判断在剪贴板观察器链中是否还存在下一个观察器。如果有,则把消息传递下去,这是剪贴板观察器程序的义务。而后判断剪贴板上内容的格式是否为位图。如是,则首先把剪贴板上内容保存到数据成员MyBitmap中,并激活一个文件保存对话框把位图保存到文件中。如果View=True,则把窗口状态(WindowState)设置为wsNormal,并把MyBitmap赋给Image部件的相应值,使用户可以对剪贴板上的位图进行观察。

源代码网整理以下 消息响应过程WMChangeCBChain在剪贴板观察器链上其它观察器退出时被调用。根据被移出观察器的不同位置决定了不同的处理方法。

源代码网整理以下procedure TClipSaveForm.WMChangeCBChain(var Msg: TWMChangeCBChain);

源代码网整理以下begin

源代码网整理以下if Msg.Remove = NextViewerHandle then

源代码网整理以下NextViewerHandle := Msg.Next

源代码网整理以下else

源代码网整理以下if NextViewerHandle <> 0 then

源代码网整理以下SendMessage(NextViewerHandle,Msg.Msg,Msg.Remove,Msg.Next);

源代码网整理以下Msg.Result := 0; 软件开发网 www.mscto.com

源代码网整理以下end;

源代码网整理以下窗口上有两个加速按钮,两个按钮。它们击键(click)事件处理过程如下。每一程序段的意义是非常显然的。 

源代码网整理以下procedure TClipSaveForm.Button1Click(Sender: TObject);

源代码网整理以下begin

源代码网整理以下Close;

源代码网整理以下end;

源代码网整理以下procedure TClipSaveForm.Button2Click(Sender: TObject);

源代码网整理以下begin

源代码网整理以下WindowState := wsMinimized;

软件开发网 www.mscto.com

源代码网整理以下end;

源代码网整理以下procedure TClipSaveForm.SpeedButton1Click(Sender: TObject);

源代码网整理以下begin

源代码网整理以下View := True;

源代码网整理以下Image1.Picture.Bitmap := MyBitmap;

源代码网整理以下end; 

源代码网整理以下procedure TClipSaveForm.SpeedButton2Click(Sender: TObject);

源代码网整理以下begin

软件开发网 www.mscto.com

源代码网整理以下View := False;

源代码网整理以下Image1.Picture.Bitmap := nil;

源代码网整理以下end; 

源代码网整理以下通过对这个程序的介绍,以下几点是应该注意的:

源代码网整理以下1.提供了一种自己截获和处理剪贴板上内容的方法。读者可以根据需要进一步扩充;

源代码网整理以下2.提供了响应Windows消息的方法。在第三篇有关自定义部件开发的内容中,这一问题还要详细论述;

源代码网整理以下3.最后的一点启示是:在Delphi程序开发中巧妙应用传统的Windows方法(如消息处理、 API函数等)仍是很有必要的。而在应用这些方法中所体现的方便之处,正是Delphi胜过其它可视化开发工具的一个重要方面。 

源代码网整理以下7.2 Windows的DDE原理和 Dephi的DDE实现机制 

源代码网整理以下7.2.1 Windows的DDE原理 

源代码网整理以下 Windows的DDE机制基于Windows的消息机制。两个Windows应用程序通过相互之间传递DDE消息进行DDE会话(Conversation),从而完成数据的请求、应答、传输。这两个应用程序分别称为服务器(Server)和客户(Client)。服务器是数据的提供者,客户是数据的请求和接受者。

源代码网整理以下 DDE会话由客户程序启动。客户程序把一条消息(WM_DDE_INITIATE)传播给当前运行的所有Windows程序。这条消息指明了客户程序所需要的一般数据(应用程序、主题)。拥有这些数据的DDE服务器可以响应这条被传播的消息。此时,DDE会话就开始了。

源代码网整理以下 由于在每个主题中,DDE服务器可以支持一个或多个数据项,所以在客户请求数据时应同时指明应用程序名、主题名和项目名。应用程序、主题、项目是DDE中三个最基本的概念。

源代码网整理以下 利用Windows本身提供的DDE消息和API进行DDE编程是一件相当棘手的问题。 虽然使用DDE管理库(ddeml.dll)可以一定程度上减轻开发者的工作负担,但开发DDE程序仍不是一件轻松的事情。

源代码网整理以下 此时Delphi出现了!Delphi通过其自身巧妙的设计使开发一个DDE应用程序同开发一个普通程序一样地快捷、方便。 

源代码网整理以下7.2.2 Delphi的DDE实现机制简介 

源代码网整理以下Delphi把所有的DDE功能做到四个部件中,它们是:

源代码网整理以下● TDDEClientConv : 用于客户程序建立和维护一个DDE会话

源代码网整理以下● TDDEClientItem : 用于客户程序建立和维护数据交换通道

源代码网整理以下● TDDEServerConv : 用于服务器程序响应DDE会话

源代码网整理以下● TDDEServerItem : 用于服务器程序维护数据交换通道 

源代码网整理以下  前两个部件用于生成一个DDE客户程序,后两个部件用于生成一个DDE服务器程序。如果一个应用程序同时拥有这些部件,则这一程序既可以充当DDE客户,也可以充当DDE服务器。

源代码网整理以下 会话部件TDDEClientConv、TDDEServerConv用于建立和维护一个DDE会话。DDE会话包括DDE服务和DDE主题两部分。

源代码网整理以下 DDE服务是DDE服务器的名称,即在一般的Windows DDE机制中所讲的应用程序名。一般说来这一名称是DDE服务器应用程序执行文件名去掉 .EXE后缀。比如你的应用程序要和Word 6.0建立会话,则DDE服务为WINWORD。但也不尽然。比如你的应用程序要和Borland ReportSmith ( RPTSMITH.EXE ) 建立会话,则DDE 服务为 Report Smith。DDE服务到底如何,读者可参看相关的DDE服务器应用程序文档。

源代码网整理以下 DDE主题是一个包含了联接信息的数据单元。一般说来DDE 主题是一个包括扩展名的完整文件名。例如和Excel中的一个文件建立DDE会话,则主题可能是 

源代码网整理以下Topic = "c:excelExamplesale.xls" 

源代码网整理以下 如果服务器是一个Delphi应用程序,缺省情况下主题是包含欲联接数据窗体的标题。如果服务器使用了DDEServerConv部件,则要求使用部件DDEServerConv的名称作为DDE主题。

源代码网整理以下 项目部件TDDEclientItem、TDDEServerItem用于建立和维护DDE数据的传输通道。 DDE项目中包含着实际欲传输的数据。DDE项目的格式取决于DDE服务器应用程序。一个可能的DDE项目例子是电子表格中的单元和数据库表中的域。如果服务器是Delphi应用程序,则项目是连接的 DDEServerItem部件的名称。

软件开发网 www.mscto.com

源代码网整理以下 Delphi的DDE实现机制方便、实用,但也有一个令人遗憾的缺陷:只能传输文本数据以及命令、宏,而不能传输图像数据。在这一点上微软公司推出的Visual Basic 要略胜一筹。不过在目前文本数据的使用仍是最广泛的,而且图像传输可以利用剪贴板和OLE来实现,则这一缺陷也并无很大的影响 

7.3 DDE客户程序的实现

源代码网整理以下 DDE客户程序启动DDE会话,向服务器请求并从服务器接收数据。同时还可以向服务器发送数据、命令、宏,改变服务器的状态并控制服务器的运行。 

软件开发网 www.mscto.com

源代码网整理以下7.3.1 联接模式(ConnectMode)

源代码网整理以下  Delphi的DDE提供了两种联接模式:自动和人工。这可以通过DDEClinetConv 部件的ConnectMode属性进行设置。如下表所示。 

源代码网整理以下表 7.5 DDE的联接模式

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

源代码网整理以下     值           意      义

源代码网整理以下───────────────────────────────

源代码网整理以下   ddeAutomatic 在运行中当包含TDDEClientConv部件的窗口创建时

源代码网整理以下联接自动建立

源代码网整理以下   ddeManual 只有当调用OpenLink方法时联接才建立

源代码网整理以下━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   

源代码网整理以下不同联接模式,DDE客户程序的实现方式不同。

源代码网整理以下对于自动模式:

软件开发网 www.mscto.com

源代码网整理以下1. 向窗体中加入DDEClientConv和DDEClientItem部件并命名;

源代码网整理以下2. 把DDEClientItem部件的DdeConv属性设置为DDEClientConv部件的名称;

源代码网整理以下如果在设计时建立,则通过对象观察器进行选择;如果在运行时建立联系, 则通过如下的一条语句设置属性的值: 

软件开发网 www.mscto.com

软件开发网 www.mscto.com

源代码网整理以下DDEClientItem1.DdeConv := "DDEClientConv1" ; 

源代码网整理以下3. 和服务器建立联系,实现数据共享。

源代码网整理以下对于人工模式:

软件开发网 www.mscto.com

源代码网整理以下1.向窗体中加入DDEClientConv部件;

源代码网整理以下2.和服务器建立联系;

源代码网整理以下3. 数据更新时调用RequestData方法申请并获得数据。 

源代码网整理以下7.3.2 和DDE服务器建立联系 

源代码网整理以下 和DDE服务器建立联系,既可以在设计时进行,也可以在运行时进行。

源代码网整理以下 在设计时,DDE联接可以通过剪贴板进行粘贴。具体步骤如下:

源代码网整理以下1. 激活服务器程序,并选中你的客户程序欲联接的数据;

源代码网整理以下2. 把数据和DDE联接信息拷贝到剪贴板上。一般说来这只需要选择服务器应用程序的 Edit|Copy 菜单;

源代码网整理以下3. 在Delphi IDE的设计窗体中选中DDEClientConv部件;

源代码网整理以下4. 在Object Inspector(对象观察器)中单击DDEService属性或DDETopic属性,然后再单击Ellipsis按钮,打开DDE Info对话框;

源代码网整理以下5.选择Paste Link按钮。此时App编辑框和Topic编辑框被自动填充。如果Paste Link按钮变灰,说明你准备用作服务器的应用程序不支持DDE或者DDE信息没有被成功地拷贝到剪贴板上;

源代码网整理以下6.选择OK 按钮。此时Object Inspector中的DDEService、DDETopic 属性包含了建立一个DDE联接的正确值。

源代码网整理以下对于人工模式以下步骤是不需要的。

源代码网整理以下7.选中DDEClientItem部件,并在Object Inspector中设置DdeConv属性为已完成联接的DDEClientConv部件名称;

源代码网整理以下8.假如剪贴板上的DDE 联接信息仍保留的话,从Object Inspector的下拉列表框中选择 DDEItem 属性的值。否则输入正确的值。

源代码网整理以下在运行时,调用 SetLink 方法来建立DDE联接。

软件开发网 www.mscto.com

源代码网整理以下 SetLink有两个String类型的参数,分别用来接受DDEService和DDETopic的值。过程执行后DDEClientConv部件的DDEService 和DDeTopic属性被设置。要注意的是:在运行时直接设置DDEService和DDETopic的值并不能建立一个DDE联接,而必须调用SetLink 方法进行初始化。

源代码网整理以下 比如,下面的语句和Excel的System主题建立联接: 

源代码网整理以下DDEClietnConv. SetLink("Excel","System"); 

源代码网整理以下 调用SetLink方法后,还需要设置DDEClientItem部件的DDEItem属性。

软件开发网 www.mscto.com

源代码网整理以下 比如,下面的语句联接Excel的Topics项目,用以获取当前活跃文件的文件名: 

源代码网整理以下DDEClietnItem.DDEItem := "Topics"; 

源代码网整理以下 当DDE联接建立后,联接的数据保存在DDEClientItem部件的Text和Lines 属性中,Text用于保存一个字符串(String),Lines用于保存一个字符串链表(TStrings)对象。

源代码网整理以下 为了显示联接数据,可以在DDEClientItem的OnChange事件中把数值赋给一个可视部件。

源代码网整理以下下面的事件过程把联接数据实时地显示在一个编辑框中。

源代码网整理以下  procedure Form1.DDEClientItemChange(Sender: Tobject);

源代码网整理以下begin

源代码网整理以下Edit1.Text := DDEClientItem1.Text;

源代码网整理以下end; 

源代码网整理以下 运行状态下也可以从剪贴板上粘贴DDE联接信息,并调用SetLink建立DDE会话。下面的例子显示了当用户按下应用程序中的Paste Link按钮时,动态建立DDE会话的过程。 

源代码网整理以下procedure Form1.OnPasteLink(Sender: Tobject);

源代码网整理以下  var

源代码网整理以下Service, Topic, Item: String;

源代码网整理以下begin

源代码网整理以下if GetPasteLinkInfo (Service, Topic, Item) then

源代码网整理以下begin

软件开发网 www.mscto.com

源代码网整理以下AppName.Text := Service;

软件开发网 www.mscto.com

源代码网整理以下TopicName.Text := Topic;

源代码网整理以下ItemName.Text := Item;

软件开发网 www.mscto.com

源代码网整理以下DDEClient.SetLink (Service, Topic);

源代码网整理以下DDEClientItem.DdeConv := DDEClient;

源代码网整理以下DDEClientItem.DDEItem := ItemName.Text;

源代码网整理以下end;

源代码网整理以下end; 

源代码网整理以下 GetPasteLinkInfo是DDEMan 库单元中定义的一个过程。如果返回True,则DDE联接信息保存在三个参数中;如果返回False,说明剪贴板上没有正确格式的DDE联接信息。 

源代码网整理以下7.3.3 数据申请 

源代码网整理以下虽然自动模式快捷、方便,但仍有一些理由使用DDE的人工模式:

源代码网整理以下1.服务器程序可能不支持自动数据传输,客户必须显式申请服务器更新一个特定的项目;

源代码网整理以下2.节省通信费用。假如没有实时传输的要求,则人工模式可以大幅度降低通信的开销;

源代码网整理以下3.若客户程序只用于控制服务器的运行,则往往没有必要使用自动模式。

源代码网整理以下 人工模式下客户程序的数据更新需要采用数据申请的方式。数据申请需要调用DDEClientConv部件的RequestData方法。RequestData有一个参数,指向要申请的DDE项目。RequestData返回一个Pchar类型的无结束符字符串,包含了申请到的文本。返回字符串占用的内存必须在程序终止前显式释放。

源代码网整理以下 在人工模式下,即使存在一个DDEClientItem部件且与DDEClientConv相联接,数据更新后DDEClientItem部件的Text、Lines属性的值也不会改变。 

源代码网整理以下7.3.4 数据发送 

源代码网整理以下 数据发送与一般的DDE数据流向正好相反,是把数据从DDE客户应用程序发送到DDE服务器应用程序。

源代码网整理以下 数据发送使用DDEClientConv部件的两个方法PokeData 和 PokeDataLines, 它们的语法是: 

源代码网整理以下  function PokeData (Item: String ; Data: PChar): Boolean;

源代码网整理以下  function PokeDataLines (Item: String ; Data: TStrings): Boolean;  软件开发网 www.mscto.com

源代码网整理以下 参数Item是DDE服务器中被联接的项目,Data是要发送的数据。如果数据是一个字符串,则把它转化为PChar类型并调用PokeData方法;如果数据是一个字符串链表对象,可调用PokeDataLines方法。

源代码网整理以下 方法的返回值标志数据传送是否成功。因为有一些DDE服务器应用程序并不接收发送的数据。

源代码网整理以下下面的语句把编辑框中的内容发送给服务器: 

源代码网整理以下  StrPCopy(TheText , Edit1.text);

软件开发网 www.mscto.com

源代码网整理以下DDEClientConv1.PokeData(DDEClientItem1.DDEItem , TheText); 

源代码网整理以下过程StrPCopy把一个Pascal类型的字符串拷贝到一个无结束符的PChar类型字符串中。 

软件开发网 www.mscto.com


源代码网推荐

源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华