【问题标题】:Embedding multiple MS Word instances in TOleContainer在 TOleContainer 中嵌入多个 MS Word 实例
【发布时间】:2013-01-14 23:01:51
【问题描述】:

这让我头疼……

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

例如,第一个 TOleContainer 的控件仍然可见并且似乎已启用但不起作用,在第一个实例中选择文本并在第二个实例中使用控件会导致更改在第一个实例中反映(像泥一样清晰?!?)一切都非常混乱,所以我附上了一张图片:

目的是将每个单词实例嵌入到它自己的形式中并利用它自己的控件。那么是什么导致了我不受欢迎的行为,我能做些什么呢?我确信这很简单,比如捕获 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);

【问题讨论】:

    标签: delphi ms-word toolbar ole


    【解决方案1】:

    您可以尝试使用 IOleInPlaceActiveObject 并在表单激活和停用时激活和停用。请参阅我的问题的公认答案:Context menu disappears with Word automation

    【讨论】:

    • 对于我醒来的任何人... 这样做的方法是捕获表单的 OnActivate/Deactivate,然后按如下方式进行转换... 如果已分配(FWordApplication),则如果支持(OleContainer1. OleObject, IOleInPlaceActiveObject, lOleInPlaceActiveObject) 然后开始 lOleInPlaceActiveObject.OnDocWindowActivate(True) end;结尾;然而,我真正需要的是 OnFrameWindowActivate,它是同一界面的一部分。当你知道怎么做时很容易!
    • @0909EM:很高兴它有帮助,我也使用了 de OnFrameWindowActivate。
    • 进一步阅读导致了这个...support.microsoft.com/kb/98678 ...虽然我可能会在我正在处理的应用程序中跳过它
    猜你喜欢
    • 2017-08-17
    • 2016-06-02
    • 2014-11-14
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多