第七章-剪贴板和动态数据交换(二)(4)

7.4 DDE服务器程序的实现 

  DDE服务器程序响应DDE客户的请求,一般地它包含了客户程序希望获取的数据。

创建一个DDE服务器程序,必须要把一个DDEServerItem部件添加到窗体中。DDEServerItem的text或Lines属性包含了要联接的数据。一般地 DDEServerItem部件又和另一个文本控件相联系。当文本控件中的内容变化时则更新DDEServerItem 的text或Lines属性的值。下面的一段程序把DDEServerItem和一个列表框相联系。这一联系是在列表框的OnChange事件中实现。 

procedure Form1.OnListBoxChange(Sender: TObject);

begin

DDEServerItem1.Lines := ListBox1.Items;

end; 

创建DDE服务器程序时也可以再加入一个DDEServerConv部件,并把两个部件利用DDEServerItem的ServerConv属性联系起来。此时DDE主题成为部件DDEServerConv的名称,而不是拥有DDEServerItem部件窗体的标题。

在下列情况下使用DDEServerConv部件成为必要:

1.拥有DDEServerItem 部件窗体的标题可能在运行时改变或可能有其它窗体拥有同样的标题。在这种情况下DDE联接可能无法建立;

2.DDE客户程序可能会向你的服务器程序发送一条宏命令。在这种情况下只有拥有一个DDEServerConv部件才能响应OnMacroExecute事件并执行相应的动作。 

7.4.1 和DDE客户程序建立联接 

一般说来,建立DDE联接是客户程序的任务。但服务器程序可以把一个联接拷贝到剪贴板上供客户程序粘贴并建立DDE会话。步骤如下:

1.调用DDEServerItem部件的CopyToClipboard方法, 把Text(或Lines)属性的值和DDE联接信息拷贝到剪贴板上;

2.DDE客户程序插入联接的数据。一般地这是通过选择适当的命令(如Edit|Paste Special或Edit|Paste Link)来实现的。

7.4.2 响应DDE事件 

部件DDEServerConv有三个事件:OnOpen、OnClose、OnExecuteMacro。前两个事件在DDE会话建立和终止时触发。同(7.3.7)中的介绍。

OnExecuteMacro事件用于响应客户程序发送过来的宏指令。OnExecuteMacro事件处理过程有一个Msg参数,保存发送过来的指令串。用户可以在该过程中决定如何响应这些宏指令。

DDEServerItem部件只有一个事件OnPokeData。这一事件用于响应客户程序发送来的数据。如果客户程序是Delphi程序,则客户程序调用了PokeData或PokeDataLines方法。在这一事件的处理过程中用户可以把发送来的数据保存到一个合适的地方。一般说来这应该就是DDEServerItem所联系的文本控件。

下面的程序把发送来的数据保存到ListBox中。

procedure Form1.OnDDEServerItemPokeData(Serder: TObject);

begin

ListBox1.Items := DDEServerItem1.Lines;

end; 

7.4.3 DDE服务器应用例程 

下面我们创建一个DDE服务器例程和一个相应的DDE客户例程。

DDE服务器例程可以完成的工作有:

1.把DDE联接信息拷贝到剪贴板上供其它程序使用;

2.利用一个TMemo部件为其它程序提供数据源;

3.接收客户程序发送来的数据;

4.根据客户程序发送来的宏指令改变自身的运行状态。

其中各部件的关键属性如下: 

DDESrvrForm.ActiveControl = Memo1

DDESrvrForm.Menu = MainMenu1

Bevel1.Align = alTop

Memo1.Align = alClient

DDETestItem.ServerConv = DDETestTopic 

通过设置Bevel1、Memo1的Align属性,可以保证窗口大小变化时仍能有较为美观的屏幕显示。

Memo1是服务器的数据源,DDE项目部件DDETestItem通过Memo1的OnChange事件与Memo1 建立联系。 

procedure TDdeSrvrForm.doOnChange(Sender: TObject);

begin

if not FInPoke then

DDETestItem.Lines := Memo1.Lines;

end; 

其中FInPoke是一个布尔类型的私有数据成员,用于标志程序是否在处理客户程序的数据发送。当数据是由客户发送过来转存到数据源时,则没有必要再把数据传给DDE项目部件。

把联接信息拷贝到剪贴板,只需简单调用DDETestItem的CopyToClipboard方法。 

procedure TDDESrvrForm.CopyClick(Sender: TObject);

begin

DDETestItem.CopyToClipboard;

end; 

这是通过菜单项Edit|Copy来调用的。

接收客户程序发送来的数据,是在DDETestItem的OnPokeData事件处理过程中。在接收过程中改变FInPoke的值,以阻止数据的无效反送。 

procedure TDDESrvrForm.doOnPoke(Sender: TObject);

begin

FInPoke := True;

Memo1.Lines := DDETestItem.Lines;

FInPoke := False;

end; 

在DDE会话部件DDETestTopic的OnExecuteMacro事件处理过程中处理客户发送来的宏指令。我们共定义了五种可以响应的宏指令:CopyDDE、Clear、WS_Normal、WS_MINIMIZED、WS_MAXIMIZED,分别用于拷贝联接信息、清除Memo1中的内容以及改变窗口显示状态。

procedure TDdeSrvrForm.doMacro(Sender: TObject;Msg: TStrings);

var

Cmd: String;

i: Integer;

begin

Cmd := '';

if Msg.Count = 0 then Exit;

for I := 0 to Msg.Count-1 do

begin

Cmd := Msg.Strings[i];

if UpperCase(Cmd) = 'COPYDDE' then

DDETestItem.CopyToClipboard

else if UpperCase(Cmd) = 'CLEAR' then

Memo1.text: = ''

else if UpperCase(Cmd) = 'WS_NORMAL' then

WindowState := wsNormal

else if UpperCase(Cmd) = 'WS_MINIMIZED' then

WindowState := wsMinimized

else if UpperCase(Cmd) = 'WS_MAXIMIZED' then

WindowState := wsMaximized

else

MessageDlg('Invalid Command',mtWarning,[mbOK],0);

end;

end; 

下面的DDE客户程序,主要是为了验证上面的DDE服务器程序而设计的,但同时也提供了一个DDE客户程序设计的完整实例。

程序把接收到的DDE数据保存在一个TMemo类部件DDEDat中,而欲发送给服务器的数据和宏指令在另一个TMemo类部件PokeDat中输入。两个按钮PokeBtn、ExecuteBtn用于发送数据和宏指令。两个菜单项File|New Link和Edit|Paste Link用于根据用户的输入建立新联接和从剪贴板上粘贴DDE联接。

时间: 2024-10-31 04:40:36

第七章-剪贴板和动态数据交换(二)(4)的相关文章

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

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

第七章-剪贴板和动态数据交换(二)(5)

DDE联接的建立通过调用SetLink方法实现. 建立新联接的实现代码如下. procedure TFormD.doNewLink(Sender: TObject); begin DDEClient.SetLink (AppName.Text, TopicName.Text); DDEClientItem.DdeConv := DDEClient; DDEClientItem.DDEItem := ItemName.Text; end; 通过从剪贴板粘贴联接信息来建立联接的实现代码如下. pro

第七章-剪贴板和动态数据交换(二)(2)

7.3.8 利用客户程序和Excel交换数据 下面我们建立一个DDE客户程序,并利用这一程序与Excel中的一个工作表交换数据.程序设计界面 界面中包含一个DDE会话部件DDEClientConv1和DDE项目部件DDEClientItem1,用于建立和维护DDE联接:一个RadioGroup控件和其中的两个无线电按钮AutoRadio.ManualRadio,用于设置联接模式:一个GroupBox控件和其中的两个按钮RequestBtn和PokeBtn,用于控制数据的申请和发送,其中Reque

第七章-剪贴板和动态数据交换(二)(3)

7.3.9 用客户程序控制程序管理器 下面的例子用客户程序向程序管理器发送命令,用于创建程序组.程序项以及删除程序组. 程序管理器提供了应用程序的DDE接口命令字符串,应用程序利用这些命令字符串可以实现以下的功能: 1.创建程序组 命令格式为: CreateGroup(程序组名[,程序组所在的路径]) 程序组不存在时进行创建:如程序组存在则按照指定的路径激活. 2.删除程序组 命令格式为: DeleteGroup(程序组名) 3.显示程序组 命令格式为: ShowGroup(程序组名,显示标志)

第七章-剪贴板和动态数据交换(二)(1)

7.3.5 控制服务器应用程序的执行 客户程序控制服务器应用程序的一个方面是:必要的时候客户程序可以启动服务器程序,并装载会话主题. 而客户程序控制服务器应用程序更重要的一点是向服务器发送服务器承认的宏命令,来完成对服务器应用程序的各种操作.服务器到底支持哪些宏命令,可参阅服务器应用程序文档. 发送宏命令要使用DDEClientConv的两个方法 ExecuteMacro和ExecuteMacroLines ,它们的语法如下: function ExecuteMacro(Cmd: PChar;

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

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(C

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

7.3.2 和DDE服务器建立联系 和DDE服务器建立联系,既可以在设计时进行,也可以在运行时进行. 在设计时,DDE联接可以通过剪贴板进行粘贴.具体步骤如下: 1. 激活服务器程序,并选中你的客户程序欲联接的数据: 2. 把数据和DDE联接信息拷贝到剪贴板上.一般说来这只需要选择服务器应用程序的 Edit|Copy 菜单: 3. 在Delphi IDE的设计窗体中选中DDEClientConv部件: 4. 在Object Inspector(对象观察器)中单击DDEService属性或DDET

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

消息响应过程WMChangeCBChain在剪贴板观察器链上其它观察器退出时被调用.根据被移出观察器的不同位置决定了不同的处理方法. procedure TClipSaveForm.WMChangeCBChain(var Msg: TWMChangeCBChain); begin if Msg.Remove = NextViewerHandle then NextViewerHandle := Msg.Next else if NextViewerHandle <> 0 then SendMe

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

为解决这些问题,我开发了下面的程序.程序启动时,以极小化方式运行.此时只要剪贴板中存入位图,则自动弹出一个对话框请求用户保存.如果用户希望查看确认,则可以双击运行程序图标,选择相应按钮,剪贴板中的位图就会显示在屏幕上. 部件关键属性设计如下: ClipSaveForm: Caption='Save Bitmap in Clipboard ' Panel1: Align = ' Top ' Image1: Align = ' Client ' SaveDialog1: FileEditStyle