在TOleContainer中嵌入多个MS Word实例

7
这让我头疼...
我正在开发的 Delphi 应用程序在 TOLEContainer 中打开一个或多个 Word 表单。 我遇到的问题是,当嵌入了多个实例的 Word 表单时,一个实例的控件会影响所有其他实例,而第一个实例上的控件无法使用。
例如,第一个 TOleContainer 的控件仍然可见并且似乎已启用,但是不起作用。 在第二个实例中选择文本和使用其控件会导致更改在第一个实例中反映出来(是否有点困惑?)非常混乱,因此我包括了一张图:
意图是使每个 Word 实例嵌入到自己的表单中,并利用它自己的控件。 那么是什么原因导致了我不期望的行为,我该怎么办呢? 我确定这很简单,例如捕获“activate”属性并设置(我不知道要设置什么)OleContainer,但我没有成功过。
我想另一种选择可能是创建自己的 TWordApplication 实例,并通过 Windows.SetParent() 进行重新父级化(顺便说一句,这确实起作用,每个实例确实可以控制自己,但需要对应用程序进行大量重新工作),或者嵌入到 OleContainer 中...我可以将 TWordApplication 实例嵌入到自己的 OleContainers 中吗?如果可以,应该怎样做呢?或者更改 CreateObjectFromFile 的默认打开行为(但我认为这是由 Word 控制的 COM 服务器)...
供参考... 通过实例化几个表单来测试以下内容...
// 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);
1个回答

6

3
对于跟随我的任何人...做法是捕获表单的 OnActivate/Deactivate,然后进行以下强制转换… if Assigned(FWordApplication) then begin if Supports(OleContainer1.OleObject, IOleInPlaceActiveObject, lOleInPlaceActiveObject) then begin lOleInPlaceActiveObject.OnDocWindowActivate(True) end; end;然而,我实际需要的是同一接口的 OnFrameWindowActivate。知道方法后很容易实现! - 0909EM
@0909EM:很高兴能够帮助到你,我也使用了OnFrameWindowActivate。 - The_Fox
1
进一步阅读后,我发现了这个链接:http://support.microsoft.com/kb/98678。虽然在我正在开发的应用程序中可能会跳过它。 - 0909EM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接