收藏 分享(赏)

Delphi剪贴板和动态数据交换.doc

上传人:j35w19 文档编号:7806515 上传时间:2019-05-26 格式:DOC 页数:35 大小:154KB
下载 相关 举报
Delphi剪贴板和动态数据交换.doc_第1页
第1页 / 共35页
Delphi剪贴板和动态数据交换.doc_第2页
第2页 / 共35页
Delphi剪贴板和动态数据交换.doc_第3页
第3页 / 共35页
Delphi剪贴板和动态数据交换.doc_第4页
第4页 / 共35页
Delphi剪贴板和动态数据交换.doc_第5页
第5页 / 共35页
点击查看更多>>
资源描述

1、应用程序间的数据交换是象 Windows 这样的多任务环境的重要特性。作为一种基于 Windows 的开发工具,Delphi 支持如下四种数据交换方式:剪贴板、动态数据交换 ( DDE)、对象联接与嵌入(OLE)以及动态联接库(DLLs)。这中间前三种方式最为常用,OLE 功能最为强大,DDE 次之。而剪贴板使用最为方便。在本章,我们只讨论剪贴板和动态数据交换。利用 OLE 实现数据交换见下一章,利用动态联接库(DLLs)进行数据交换将在第十章中介绍。 7.1 剪贴板及其应用 本质上,剪贴板只是一个全局内存块。当一个应用程序将数据传送给剪贴板后,通过修改内存块分配标志,把相关内存块的所有权从应

2、用程序移交给 Windows 自身。其它应用程序可以通过一个句柄找到这个内存块,从而能够从内存块中读取数据。这样就实现了数据在不同应用程序间的传输。 剪贴板虽然功能较为简单,且不能实现实时传输,但却是更为复杂的 DDE 和 OLE的基础。对于一些只是偶尔需要使用其它应用程序数据的程序来说,使用剪贴板不失为一种方便、快捷的方式。Delphi 把剪贴板的大部分功能封装到一个 TClipboard 类中,同时把使用频度最高的文本传输功能(包括 DBImage 的图像传输功能)置入相应部件作为部件的方法,从而使用户可以十分方便地使用剪贴板进行编程。 7.1.1 使用剪贴板传输文本 剪贴板传输文本主要是

3、应用如下的三个方法:CopyToClipboard、CutToClipboard 和 PasteFromClipboard。包含这些方法的部件如下表所示。 表 7.1 包含剪贴板方法的部件方 法 部 件TDBEdit TDBMemoTDBImageCopyToClipboard TEdit TMemo TMaskEditTOLEContainerTDDEServerItemTDBEdit TDBMemoCutToClipboard TDBImageTEdit TMemo TMaskEditTDBEdit TDBMemoPasteFromClipboard TDBImageTEdit TMemo

4、 TMaskEdit 除 TDBImage 外,其余全是有关文本的控件。在把文本传输到剪贴板之前,文本必须被选中。若选 TMaskEdit 的 AutoSelect 属性为 True,则当 MaskEdit 获得输入焦点时文本自动被选中;若选 TEdit、TMemo 的 HideSelection 属性为 True,则失去焦点时,文本选中状态自动隐藏,重新获得焦点时再显示。下面的语句把 MaskEdit 中选中的文本剪切到剪贴板: MaskEdit .CutToClipboard; 下面的语句把剪贴板中的文本粘贴到 Memo 的当前光标处: Memo.PasteFromClipboard; 利

5、用剪贴板类也可以实现文本的传输,见(7.1.2)中的介绍。 7.1.2 剪贴板类 为方便剪贴板的操作,Delphi 在 Clipbrd 库单元中定义了一个 TClipboard 类,并且预定义了一个变量 Clipboard 作为类 TClipboard 的实例,从而使用户在绝大多数场合不必自己去定义一个 TClipboard 的实例。利用剪贴板类可以进行文本、图像和部件的传输,剪贴板类为实现这些方法提供了相应的属性和方法。表 7.2、表 7.3 列出了 TClipboard 属性和方法的意义。 表 7.2 TClipboard 的属性属 性 意 义AsText 保存剪贴板的文本,只有运行时才可

6、设置FormatCount 可用剪贴板格式的数目Formats 可用剪贴板格式链 表 7.3 TClipboard 的方法方 法 参 数 意 义Clear 无 清除剪贴板的内容Assign Source:TPersistent 把 Source 参数指定的对象拷贝到剪贴板,常用于图形、图像对象Open 无打开剪贴板,阻止其它应用程序改变它的内容Close 无 关闭打开的剪贴板SetComponent Source:TPersistent 把部件拷贝到剪贴板GetComponent Owner 从剪贴板取回一个部件并放置Parent :TPersistentSetAsHandle Format:

7、Word 把指定格式数据的句柄交给剪贴板返回类型:THandleGetAsHandle Format:Word 返回剪贴板指定格式数据的句柄返回类型:THandleHasFormat Format:Word 判断剪贴板是否拥有给定的格式返回类型:BooleanSetTextBuf Buffer:PChar 设置剪贴板的文本内容 剪贴板中可能的数据格式如下表。 表 7.4 剪贴板数据格式及其意义数据格式 意 义CF_TEXT 文本。每行以 CF_LF 结束,nil 标志文本结束CF_BITMAP Windows 位图CF_METAFILE Windows 元文件 CF_PICTURE TPict

8、ure 类型的对象CF_OBJECT 任何 TPersistent 类型的对象 利用 TClipboard 实现文本的传输使用 AsText 属性和 SetTextBuf 方法。AsText 属性为非控件部件的剪贴板操作提供了方便。如: Clipboard. AsText := Form1.Caption ; 把 Form1 的标题拷贝到剪贴板。 Label1.Caption := Clipboard.AsText; 把剪贴板中的文本写入 Label1。SetTextBuf 用于把超过 255 个字符的字符串拷入剪贴板。 7.1.3 利用剪贴板传输图像 7.1.3.1 拷贝 Image 部件上

9、的内容和窗体上的图形可以直接拷贝到剪贴板。图像拷贝利用 Clipboard 的 Assign 方法。例如: Clipboard.Assign(Image1.Picture); 把 Image1 上的图像拷贝到剪贴板。 7.1.3.2 剪切 图像的剪切是首先把图像拷贝到剪贴板,而后在原位置用空白图像进行覆盖。下面一段程序表示了图像的剪切。 procedure TForm1.Cut1Click(Sender: TObject);varARect: TRect;beginClipboard.Assign(Image1.Picture);with Image.Canvas dobeginCopyMod

10、e := 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);varBitmap: TBitmap;beginif Clipb

11、oard.HasFormat(CF_BITMAP) then beginBitmap := TBitmap.Create; tryBitmap.Assign(Clipboard); Image.Canvas.Draw(0, 0, Bitmap); finallyBitmap.Free;end;end;end; try.finally 为资源保护块,参第十二章。7.1.4 建立自己的剪贴板观察程序 在这一节中我们要建立一个自己的剪贴板观察程序,用来保存截获到剪贴板中的位图。Windows 允许用户建立自己的剪贴板观察程序,并把该程序添加到一个剪贴板观察器链中。在链中,位置靠前的程序有义务把有关剪

12、贴板的消息传递到紧随其后的观察程序。而处于链首的程序由 Windows 的消息循环机制直接把剪贴板消息发送过来。建立一个剪贴板观察程序,首先该程序必须能响应相应的 Windows 消息。对于那些熟悉 Microsoft 公司 Visual Basic 的读者来说,这是令他们头疼而束手无策的地方。但 Delphi 在这方面却有良好的表现:利用关键字 message,用户可以将一个过程定义为响应特定的 Windows 消息。如: procedure WMDrawClipboard(var Msg:TWMDrawClipboard);message WM_DRAWCLIPBOARD; 可以响应 WM

13、_DRAWCLIPBOARD 消息。类 TWMDrawClipboard 是消息类 Message 的子类。Delphi 把所有的消息都重新进行了定义,使用户在使用时可以直接引用其便于记忆的数据成员,而不必再自己动手去分解消息。虽然这并不能算作是一个重大的改进,但却体现了 Delphi 处处为用户方便着想的特点。我们将要建立的程序目的是把截获到剪贴板上的位图保存下来。在本书的写作过程中,这一工作是大量存在的。虽然利用 Windows 工具 PaintBrush(画笔),通过粘贴、保存等操作可以实现这一功能,但却存在以下一些问题:1.程序频繁切换影响效率,当有大量位图存在时更是如此;2.画笔有一

14、个很讨厌的缺陷:当剪贴板上的位图比画笔界面的客户区大时,客户区外的位图被截断。因而往往需要根据所截获位图的大小来调整画笔客户区的大小,并重新进行粘贴。而如果开始就把画笔客户区调整到足够大,又会覆盖掉屏幕上一些有用的信息。为解决这些问题,我开发了下面的程序。程序启动时,以极小化方式运行。此时只要剪贴板中存入位图,则自动弹出一个对话框请求用户保存。如果用户希望查看确认,则可以双击运行程序图标,选择相应按钮,剪贴板中的位图就会显示在屏幕上。部件关键属性设计如下: ClipSaveForm:CaptionSave Bitmap in Clipboard Panel1:Align = Top Image

15、1:Align = Client SaveDialog1:FileEditStyle = fsEditFileName = *.bmpFilter = Bitmap Files(*.bmp)|*.bmp|Any Files(*.*)|*.*InitialDir = c:bmpTitle = Save Bitmap 程序主窗口是 TForm 派生类 TClipSaveForm 的实例。TClipSaveForm 通过定义一些私有数据成员和过程,使响应和处理 Windows 的相应消息成为可能。下面是 TClipSaveForm 的类定义: typeTClipSaveForm = class(TF

16、orm)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: TObje

17、ct);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 WMCha

18、ngeCBChain(var Msg:TWMChangeCBChain);message WM_CHANGECBCHAIN; 响应 Windows 的剪贴板消息 public Public declarations end;窗口创建时,把该窗口登录为剪贴板观察器,添加到剪贴板观察器链中,同时进行变量、部件和剪贴板的初始化。 procedure TClipSaveForm.FormCreate(Sender: TObject);beginView := False;SpeedButton2.Down := True;MyBitmap := TBitmap.create;tryMyBitmap.W

19、idth := 0;MyBitmap.Height := 0 ;exceptApplication.terminate;end;Clipboard.Clear;NextViewerHandle := SetClipboardViewer(Handle);end; 窗口关闭时,退出剪贴板观察器链,并释放内存: procedure TClipSaveForm.FormDestroy(Sender: TObject);beginChangeClipboardChain(Handle,NextViewerHandle);MyBitmap.Free;end; 在以上两段程序中用到的两个 Windows

20、API 函数 SetClipboardViewer 和 ChangeClipboardChain 分别用于登录和退出剪贴板观察器链。程序保存位图的功能是在消息响应过程 WMDrawClipboard 中实现的。该过程在剪贴板内容有变化时被调用。 procedure TClipSaveForm.WMDrawClipboard(var Msg: TWMDrawClipboard);varFileName: String;beginIf NextViewerHandle 0 thenSendMessage(NextViewerHandle,Msg.Msg,Msg.Remove,Msg.Next);M

21、sg.Result := 0;end;窗口上有两个加速按钮,两个按钮。它们击键(click)事件处理过程如下。每一程序段的意义是非常显然的。 procedure TClipSaveForm.Button1Click(Sender: TObject);beginClose;end;procedure TClipSaveForm.Button2Click(Sender: TObject);beginWindowState := wsMinimized;end;procedure TClipSaveForm.SpeedButton1Click(Sender: TObject);beginView :

22、= True;Image1.Picture.Bitmap := MyBitmap;end; procedure TClipSaveForm.SpeedButton2Click(Sender: TObject);beginView := False;Image1.Picture.Bitmap := nil;end; 通过对这个程序的介绍,以下几点是应该注意的:1.提供了一种自己截获和处理剪贴板上内容的方法。读者可以根据需要进一步扩充;2.提供了响应 Windows 消息的方法。在第三篇有关自定义部件开发的内容中,这一问题还要详细论述;3.最后的一点启示是:在 Delphi 程序开发中巧妙应用传统

23、的 Windows 方法(如消息处理、 API 函数等)仍是很有必要的。而在应用这些方法中所体现的方便之处,正是 Delphi 胜过其它可视化开发工具的一个重要方面。 7.2 Windows 的 DDE 原理和 Dephi 的 DDE 实现机制 7.2.1 Windows 的 DDE 原理 Windows 的 DDE 机制基于 Windows 的消息机制。两个 Windows 应用程序通过相互之间传递 DDE 消息进行 DDE 会话(Conversation),从而完成数据的请求、应答、传输。这两个应用程序分别称为服务器(Server)和客户(Client)。服务器是数据的提供者,客户是数据的

24、请求和接受者。DDE 会话由客户程序启动。客户程序把一条消息(WM_DDE_INITIATE)传播给当前运行的所有 Windows 程序。这条消息指明了客户程序所需要的一般数据(应用程序、主题)。拥有这些数据的 DDE 服务器可以响应这条被传播的消息。此时,DDE 会话就开始了。由于在每个主题中,DDE 服务器可以支持一个或多个数据项,所以在客户请求数据时应同时指明应用程序名、主题名和项目名。应用程序、主题、项目是 DDE 中三个最基本的概念。利用 Windows 本身提供的 DDE 消息和 API 进行 DDE 编程是一件相当棘手的问题。 虽然使用 DDE 管理库(ddeml.dll)可以一

25、定程度上减轻开发者的工作负担,但开发 DDE 程序仍不是一件轻松的事情。此时 Delphi 出现了!Delphi 通过其自身巧妙的设计使开发一个 DDE 应用程序同开发一个普通程序一样地快捷、方便。 7.2.2 Delphi 的 DDE 实现机制简介 Delphi 把所有的 DDE 功能做到四个部件中,它们是: TDDEClientConv : 用于客户程序建立和维护一个 DDE 会话 TDDEClientItem : 用于客户程序建立和维护数据交换通道 TDDEServerConv : 用于服务器程序响应 DDE 会话 TDDEServerItem : 用于服务器程序维护数据交换通道 前两个

26、部件用于生成一个 DDE 客户程序,后两个部件用于生成一个 DDE 服务器程序。如果一个应用程序同时拥有这些部件,则这一程序既可以充当 DDE 客户,也可以充当 DDE 服务器。会话部件 TDDEClientConv、TDDEServerConv 用于建立和维护一个 DDE 会话。DDE会话包括 DDE 服务和 DDE 主题两部分。DDE 服务是 DDE 服务器的名称,即在一般的 Windows DDE 机制中所讲的应用程序名。一般说来这一名称是 DDE 服务器应用程序执行文件名去掉 .EXE 后缀。比如你的应用程序要和 Word 6.0 建立会话,则 DDE 服务为 WINWORD。但也不尽

27、然。比如你的应用程序要和 Borland ReportSmith ( RPTSMITH.EXE ) 建立会话,则 DDE 服务为 Report Smith。DDE 服务到底如何,读者可参看相关的 DDE 服务器应用程序文档。DDE 主题是一个包含了联接信息的数据单元。一般说来 DDE 主题是一个包括扩展名的完整文件名。例如和 Excel 中的一个文件建立 DDE 会话,则主题可能是 Topic = c:excelExamplesale.xls 如果服务器是一个 Delphi 应用程序,缺省情况下主题是包含欲联接数据窗体的标题。如果服务器使用了 DDEServerConv 部件,则要求使用部件

28、DDEServerConv 的名称作为DDE 主题。项目部件 TDDEclientItem、TDDEServerItem 用于建立和维护 DDE 数据的传输通道。 DDE 项目中包含着实际欲传输的数据。DDE 项目的格式取决于 DDE 服务器应用程序。一个可能的 DDE 项目例子是电子表格中的单元和数据库表中的域。如果服务器是 Delphi 应用程序,则项目是连接的 DDEServerItem 部件的名称。Delphi 的 DDE 实现机制方便、实用,但也有一个令人遗憾的缺陷:只能传输文本数据以及命令、宏,而不能传输图像数据。在这一点上微软公司推出的 Visual Basic 要略胜一筹。不过

29、在目前文本数据的使用仍是最广泛的,而且图像传输可以利用剪贴板和 OLE 来实现,则这一缺陷也并无很大的影响 7.3 DDE 客户程序的实现DDE 客户程序启动 DDE 会话,向服务器请求并从服务器接收数据。同时还可以向服务器发送数据、命令、宏,改变服务器的状态并控制服务器的运行。 7.3.1 联接模式(ConnectMode)Delphi 的 DDE 提供了两种联接模式:自动和人工。这可以通过 DDEClinetConv 部件的ConnectMode 属性进行设置。如下表所示。 表 7.5 DDE 的联接模式值 意 义ddeAutomatic 在运行中当包含 TDDEClientConv 部件

30、的窗口创建时联接自动建立ddeManual 只有当调用 OpenLink 方法时联接才建立 不同联接模式,DDE 客户程序的实现方式不同。对于自动模式:1. 向窗体中加入 DDEClientConv 和 DDEClientItem 部件并命名;2. 把 DDEClientItem 部件的 DdeConv 属性设置为 DDEClientConv 部件的名称;如果在设计时建立,则通过对象观察器进行选择;如果在运行时建立联系, 则通过如下的一条语句设置属性的值: DDEClientItem1.DdeConv := DDEClientConv1 ; 3. 和服务器建立联系,实现数据共享。对于人工模式:

31、1.向窗体中加入 DDEClientConv 部件;2.和服务器建立联系;3. 数据更新时调用 RequestData 方法申请并获得数据。 7.3.2 和 DDE 服务器建立联系 和 DDE 服务器建立联系,既可以在设计时进行,也可以在运行时进行。在设计时,DDE 联接可以通过剪贴板进行粘贴。具体步骤如下:1. 激活服务器程序,并选中你的客户程序欲联接的数据;2. 把数据和 DDE 联接信息拷贝到剪贴板上。一般说来这只需要选择服务器应用程序的 Edit|Copy 菜单;3. 在 Delphi IDE 的设计窗体中选中 DDEClientConv 部件;4. 在 Object Inspecto

32、r(对象观察器)中单击 DDEService 属性或 DDETopic 属性,然后再单击 Ellipsis 按钮,打开 DDE Info 对话框;5.选择 Paste Link 按钮。此时 App 编辑框和 Topic 编辑框被自动填充。如果 Paste Link按钮变灰,说明你准备用作服务器的应用程序不支持 DDE 或者 DDE 信息没有被成功地拷贝到剪贴板上;6.选择 OK 按钮。此时 Object Inspector 中的 DDEService、DDETopic 属性包含了建立一个 DDE 联接的正确值。对于人工模式以下步骤是不需要的。7.选中 DDEClientItem 部件,并在 O

33、bject Inspector 中设置 DdeConv 属性为已完成联接的DDEClientConv 部件名称;8.假如剪贴板上的 DDE 联接信息仍保留的话,从 Object Inspector 的下拉列表框中选择 DDEItem 属性的值。否则输入正确的值。在运行时,调用 SetLink 方法来建立 DDE 联接。SetLink 有两个 String 类型的参数,分别用来接受 DDEService 和 DDETopic 的值。过程执行后 DDEClientConv 部件的 DDEService 和 DDeTopic 属性被设置。要注意的是:在运行时直接设置 DDEService 和 DDE

34、Topic 的值并不能建立一个 DDE 联接,而必须调用SetLink 方法进行初始化。比如,下面的语句和 Excel 的 System 主题建立联接: DDEClietnConv. SetLink(Excel,System); 调用 SetLink 方法后,还需要设置 DDEClientItem 部件的 DDEItem 属性。比如,下面的语句联接 Excel 的 Topics 项目,用以获取当前活跃文件的文件名: DDEClietnItem.DDEItem := Topics; 当 DDE 联接建立后,联接的数据保存在 DDEClientItem 部件的 Text 和 Lines 属性中,T

35、ext 用于保存一个字符串(String),Lines 用于保存一个字符串链表(TStrings)对象。为了显示联接数据,可以在 DDEClientItem 的 OnChange 事件中把数值赋给一个可视部件。下面的事件过程把联接数据实时地显示在一个编辑框中。procedure Form1.DDEClientItemChange(Sender: Tobject);beginEdit1.Text := DDEClientItem1.Text;end; 运行状态下也可以从剪贴板上粘贴 DDE 联接信息,并调用 SetLink 建立 DDE 会话。下面的例子显示了当用户按下应用程序中的 Paste

36、Link 按钮时,动态建立 DDE 会话的过程。 procedure Form1.OnPasteLink(Sender: Tobject);varService, Topic, Item: String;beginif GetPasteLinkInfo (Service, Topic, Item) thenbeginAppName.Text := Service;TopicName.Text := Topic;ItemName.Text := Item;DDEClient.SetLink (Service, Topic); DDEClientItem.DdeConv := DDEClient;

37、DDEClientItem.DDEItem := ItemName.Text;end;end; GetPasteLinkInfo 是 DDEMan 库单元中定义的一个过程。如果返回 True,则 DDE联接信息保存在三个参数中;如果返回 False,说明剪贴板上没有正确格式的 DDE 联接信息。 7.3.3 数据申请 虽然自动模式快捷、方便,但仍有一些理由使用 DDE 的人工模式:1.服务器程序可能不支持自动数据传输,客户必须显式申请服务器更新一个特定的项目;2.节省通信费用。假如没有实时传输的要求,则人工模式可以大幅度降低通信的开销;3.若客户程序只用于控制服务器的运行,则往往没有必要使用自

38、动模式。人工模式下客户程序的数据更新需要采用数据申请的方式。数据申请需要调用 DDEClientConv 部件的 RequestData 方法。RequestData 有一个参数,指向要申请的 DDE 项目。RequestData 返回一个 Pchar 类型的无结束符字符串,包含了申请到的文本。返回字符串占用的内存必须在程序终止前显式释放。在人工模式下,即使存在一个 DDEClientItem 部件且与 DDEClientConv 相联接,数据更新后 DDEClientItem 部件的 Text、Lines 属性的值也不会改变。 7.3.4 数据发送 数据发送与一般的 DDE 数据流向正好相反

39、,是把数据从 DDE 客户应用程序发送到DDE 服务器应用程序。数据发送使用 DDEClientConv 部件的两个方法 PokeData 和 PokeDataLines, 它们的语法是: function PokeData (Item: String ; Data: PChar): Boolean;function PokeDataLines (Item: String ; Data: TStrings): Boolean; 参数 Item 是 DDE 服务器中被联接的项目,Data 是要发送的数据。如果数据是一个字符串,则把它转化为 PChar 类型并调用 PokeData 方法;如果数据

40、是一个字符串链表对象,可调用 PokeDataLines 方法。 方法的返回值标志数据传送是否成功。因为有一些 DDE 服务器应用程序并不接收发送的数据。下面的语句把编辑框中的内容发送给服务器: StrPCopy(TheText , Edit1.text);DDEClientConv1.PokeData(DDEClientItem1.DDEItem , TheText); 过程 StrPCopy 把一个 Pascal 类型的字符串拷贝到一个无结束符的 PChar 类型字符串中。 7.3.5 控制服务器应用程序的执行 客户程序控制服务器应用程序的一个方面是:必要的时候客户程序可以启动服务器程序,

41、并装载会话主题。而客户程序控制服务器应用程序更重要的一点是向服务器发送服务器承认的宏命令,来完成对服务器应用程序的各种操作。服务器到底支持哪些宏命令,可参阅服务器应用程序文档。发送宏命令要使用 DDEClientConv 的两个方法 ExecuteMacro 和 ExecuteMacroLines ,它们的语法如下: function ExecuteMacro(Cmd: PChar; WaitFlag: Boolean): Boolean;function ExecuteMacroLines(Cmd: TStrings;WaitFlag: Boolean): Boolean; Cmd 是欲发送

42、的宏命令字符串或宏命令字符串链表。WaitFlag 决定了在 DDE 服务器程序执行宏命令时客户程序的行为。如果 WaitFlag 设置为 True,则在服务器宏命令执行完毕前,不允许对 ExecuteMacro、ExecuteMacroLines、PokeData、PokeDataLines 这些方法的成功调用,它们都不向服务器发送数据并返回 False。如果 WaitFlag 设置为 False,则调用的方法在第一个宏执行完毕前即试图向服务器发送数据。WaitFalg 的设置也取决于服务器应用程序。一些应用程序当在第一个宏执行完之前就试图向它发送数据或命令时,可能导致第一个宏执行失败或导致

43、不可预料的后果。具体情况可查阅服务器应用程序文档。函数返回值表示命令串是否被成功传输。而宏命令执行是否成功客户是无法检测到的。 7.3.6 格式化文本 DDEClientConv 有一个布尔属性 FormartChars,用于决定是否格式化文本。所谓格式化文本是指从传输来的文本数据中过滤掉 BackSpace(8)、 Tab(7) 、Linefeed(10) 、Return(13)等字符。括号内是字符的 ASCII 码。许多时候这些字符将导致 DDE 客户数据显示的混乱。FormatChars 的缺省值是 False。 7.3.7 响应 DDE 事件 部件 DDEClientConv 有两个事

44、件 OnOpen 和 OnClose,分别在 DDE 会话建立和中止时触发。部件 DDEClientItem 有一个 OnChange 事件。这一事件常用于 DDE 项目数据的转储和显示,如(7.3.1)节所示。在自动模式下,OnOpen 事件在包含 DDEClientConv 部件的窗口创建时触发,或在调用 SetLink 方法时触发,OnClose 事件在客户程序或服务器程序关闭时触发。在人工模式下,OnOpen 事件在调用 OpenLink 方法时触发,OnClose 事件在调用 ColseLink 方法时触发。 7.3.8 利用客户程序和 Excel 交换数据 下面我们建立一个 DDE

45、 客户程序,并利用这一程序与 Excel 中的一个工作表交换数据。程序设计界面界面中包含一个 DDE 会话部件 DDEClientConv1 和 DDE 项目部件 DDEClientItem1,用于建立和维护 DDE 联接;一个 RadioGroup 控件和其中的两个无线电按钮 AutoRadio、ManualRadio,用于设置联接模式;一个 GroupBox 控件和其中的两个按钮 RequestBtn 和 PokeBtn,用于控制数据的申请和发送,其中 RequestBtn 在自动模式下变灰;一个文本框 Memo1 用于保存 DDE 数据;一个按钮 PasteBtn 用于粘贴联接信息并建立

46、 DDE 联接;另外一个按钮 CloseBtn 用于关闭系统。设计时把 DDEClientConv1 的 FormatChars 属性置为 True,这样可以保留服务器传来数据的显示格式;ConnectMode 保留 ddeAutomatic 的缺省设置。程序在类 TForm1 中定义了一个私有数据成员 Automatic,用于标志联接模式;三个字符串数据成员 DDEService、DDETopic、DDEItem 用于记录联接信息。窗口生成时进行变量和部件状态的初始化。 procedure TForm1.FormCreate(Sender: TObject);beginRequestBtn.

47、Enabled := False;AutoRadio.Checked := True;Automatic := True;end; 当联接模式改变时,程序进行相应的处理。自动模式转换为人工模式: procedure TForm1.ManualRadioClick(Sender: TObject);beginif Automatic thenbeginRequestBtn.Enabled := ManualRadio.Checked;DDEClientConv1.ConnectMode := ddeManual;Automatic := False;end;end; 人工模式转换为自动模式:pr

48、ocedure TForm1.AutoRadioClick(Sender: TObject);beginif not Automatic thenbeginRequestBtn.Enabled := ManualRadio.Checked;If (DDEService = ) or (DDETopic = ) thenbeginMessageDlg( Can not Set Link.,mtWarning,mbOK,0);Exit;end;DDEClientConv1.SetLink (DDEService, DDETopic);DDEClientItem1.DdeConv := DDEClientConv1;DDEClientI

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报