在TOleContainer中嵌入多个MS Word实例 [英] Embedding multiple MS Word instances in TOleContainer

查看:253
本文介绍了在TOleContainer中嵌入多个MS Word实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这让我头疼...

我正在使用的delphi应用程序在TOLEContainer中使用Word打开一个或多个表单.我的问题是,当使用嵌入式Word实例打开多个窗体时,一个实例的控件会影响所有其他实例,而第一个实例上的控件不可用.

例如,第一个TOleContainer的控件仍然可见并且似乎已启用,但是不起作用,在第一个实例中选择文本并在第二个实例中使用控件会使更改反映在第一个实例中(像泥一样清澈?!?)所有这些都很令人困惑,所以我附上了一张照片:

目的是使单词的每个实例以其自身的形式嵌入并利用其自身的控件.那么,是什么导致了我的不良行为,我该怎么办?我敢肯定这很简单,例如捕获OleContainer的"activate"属性和设置(我不知道要设置什么),但是我对此并不走运.

我认为一个替代方案可能是创建自己的TWordApplication实例,然后通过Windows.SetParent()重新创建父对象(此方法确实有效,顺便说一句,每个实例都可以控制自己,但需要对应用程序进行大量修改)或嵌入OleContainer中...我可以将TWordApplication实例嵌入其自己的OleContainer中吗?如果可以,怎么办?或者,更改CreateObjectFromFile的默认打开行为(但我认为这是由COM服务器Word控制的).

作为参考....通过实例化几种形式来测试以下内容...

// This embed into an OleContainer, but opening two forms 
// leaves me with one that has working controls and another 
// that has non-working controls (this code on it's own form)
// If this code is on TForm2 and you create two instances of TForm2
// Word behaves incorrectly
OleContainer1.CreateObjectFromFile('C:\Test.docx', false);
OleContainer1.AutoActivate := aaGetFocus;
OleContainer1.DoVerb(ovOpen);

OleContainer1.Run;


//  To embed Word on a TPanel (this code on it's own form)
//  This code on TForm3, create two instance of TForm3 to see 
//  word work independently as desired
wordApp := TWordApplication.Create(Self);
wordApp.ConnectKind := TConnectKind.ckNewInstance;
wordApp.Caption := IntToStr(AppId);
wordApp.Visible := True;

WordHandle := FindWindow('OpusApp', PWideChar(wordApp.Caption));

Windows.SetParent(WordHandle, Panel1.Handle);

if AppId = 1 then
begin
  lFilename := 'C:\Test.docx';
end else begin
  lFilename := 'C:\Test2.docx';
end;
wordApp.Documents.Open(lFileName, EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam);

解决方案

您可以尝试使用IOleInPlaceActiveObject并在激活和停用表单时激活和停用.请参阅我的问题的已接受答案:上下文菜单随着Word自动化而消失

This is giving me a headache...

The delphi App I'm working on opens one or more forms with Word in a TOLEContainer. The problem I have is that when more than one form is opened with an embedded instance of Word, the controls of one instance affects all other instances whilst the controls on the first instance are unusable.

The controls for the first TOleContainer, for example, are still visible and appear to be enabled but are non-functional, selecting text in the first instance and using the controls in the second instance cause the changes to be reflected in first instance (clear as mud?!?) All very confusing so I've included a picture:

The intention is to have each instance of word embedded in it's own form and utilising it's own controls. So what causes my undesired behaviour and what can I do about it? I'm sure it's something simple, like catching the "activate" property and setting (I dont know what to set) of the OleContainer, but I've had no luck with this.

I figure one alternative might be to create my own instances of TWordApplication and either re-parent via Windows.SetParent() (this does work, btw, each instance does control itself but would require a lot of rework of the application) or embed in an OleContainer... can I embed TWordApplication instances their own OleContainers? If so how so? Alternatively changing the default open behaviour of CreateObjectFromFile (but I think this is controlled by the COM server which is Word)...

For reference.... Test the following by instantiating a couple of forms...

// This embed into an OleContainer, but opening two forms 
// leaves me with one that has working controls and another 
// that has non-working controls (this code on it's own form)
// If this code is on TForm2 and you create two instances of TForm2
// Word behaves incorrectly
OleContainer1.CreateObjectFromFile('C:\Test.docx', false);
OleContainer1.AutoActivate := aaGetFocus;
OleContainer1.DoVerb(ovOpen);

OleContainer1.Run;


//  To embed Word on a TPanel (this code on it's own form)
//  This code on TForm3, create two instance of TForm3 to see 
//  word work independently as desired
wordApp := TWordApplication.Create(Self);
wordApp.ConnectKind := TConnectKind.ckNewInstance;
wordApp.Caption := IntToStr(AppId);
wordApp.Visible := True;

WordHandle := FindWindow('OpusApp', PWideChar(wordApp.Caption));

Windows.SetParent(WordHandle, Panel1.Handle);

if AppId = 1 then
begin
  lFilename := 'C:\Test.docx';
end else begin
  lFilename := 'C:\Test2.docx';
end;
wordApp.Documents.Open(lFileName, EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam);

解决方案

You could try working with IOleInPlaceActiveObject and activate and deactivate when your form activates and deactivates. See the accepted answer to my question: Context menu disappears with Word automation

这篇关于在TOleContainer中嵌入多个MS Word实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆