7

MS Word を TForm に埋め込んで制御する方法として、レイアウトに関してどのような提案があるのだろうか? 現在、私は (1) TForm に 2 つの TPanel を配置しています。TPanel には 1 つのalBottomTButton があり、alClientTPanel にはalNoneTOleContainer があります。(2) TMainForm.FormCreate イベント ハンドラでレイアウトを設定します。

問題は、MS Word がその親フォームのすべてのスペースを占有することです。以下に示す 4 番目の方法のみが、適切なレイアウトを提供するようです。試行錯誤の結果、TOleContainer をホストするために TPanel の代わりにサブフォームを使用する必要があるようです。(また、Windows.SetParent が必要なようです。) サブフォームが正しい方法なのだろうか?

PS: Delphi XE、Word 2010、Windows 7

PS: 「外部アプリケーションのホスティング」に関連する Web ページ:

Binh Lyのサイト

デボラのサイト

別のアプリにシェルし、それを Delphi 形式で表示する方法

TOleContainerの再訪

デルファイでWord文書を開きますか?

Delphi & Word (SimpChn)

PS: 「パネル内のフォーム (サブフォーム)」に関連する Web ページ:

パネル内に透明なフォームを作成する方法は?

Delphi - OleContainer - PowerPoint - 自動再生

FreePascal/Lazarus MultiDoc

パネル内の TForm

移動/サイズ変更してアクティブ化できる複数の「子」フォームを含む Delphi フォームを作成する方法

サンプルコード

unit uMainForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtnrs, ExtCtrls, StdCtrls;

type
  TMainForm = class(TForm)
    PanelOle: TPanel;
    PanelBtn: TPanel;
    OleContainer1: TOleContainer;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
var
  OleForm: TForm;
begin
////
//// 1
////
//  OleContainer1.Parent := PanelOle;
//  OleContainer1.Align := alClient;
//
////
//// 2
////
//  Windows.SetParent(OleContainer1.Handle, PanelOle.Handle);
//  OleContainer1.Align := alClient;
//
////
//// 3
////
//  OleForm := TForm.Create(Self);
//  OleForm.Parent := PanelOle;
//  OleForm.Align := alClient;
//  OleForm.Visible := True;
//  OleContainer1.Parent := OleForm;
//  OleContainer1.Align := alClient;
//
////
//// 4 Works!
////
//  OleForm := TForm.Create(Self);
//  Windows.SetParent(OleForm.Handle, PanelOle.Handle);
//  OleForm.Align := alClient;
//  OleForm.Visible := True;
//  OleContainer1.Parent := OleForm;
//  OleContainer1.Align := alClient;
//
////
//// 5
////
//  OleForm := TForm.Create(Self);
//  OleForm.Parent := PanelOle;
//  OleForm.Align := alClient;
//  OleForm.Visible := True;
//  Windows.SetParent(OleContainer1.Handle,OleForm.Handle);
//  OleContainer1.Align := alClient;
//
////
//// 6
////
//  OleForm := TForm.Create(Self);
//  Windows.SetParent(OleForm.Handle, PanelOle.Handle);
//  OleForm.Align := alClient;
//  OleForm.Visible := True;
//  Windows.SetParent(OleContainer1.Handle,OleForm.Handle);
//  OleContainer1.Align := alClient;

end;

procedure TMainForm.Button1Click(Sender: TObject);
var
// Declare the item to be a generic OleVariant to force late binding
  Ds: OleVariant;
  D: OleVariant;
begin
  OleContainer1.CreateObjectFromFile('sample.docx', False);

  OleContainer1.Run;

  OleContainer1.AutoActivate := aaManual;
  OleContainer1.DoVerb(ovShow);  // not in FormCreate, in or after FormShow

  Ds := OleContainer1.OleObject.Application.Documents;
  Caption := IntToStr(Ds.Count);
end;

end.
4

1 に答える 1

2

サブフォームはそれを行う正しい方法です。このアプローチを本番環境で使用したところ、うまくいきました。「サブ」フォームをパネルにホストしました。ただし、TOleContainer と TOleForm を、親フォームを使用するか最上位フォームを使用するかのフラグで変更しました。

procedure TOurOleContainer.InitObject;
...
begin
  if FDrawInTopForm then
    DocForm := GetParentForm(Self)
  else
    DocForm := TCustomForm(Parent);
...

FDrawInTopForm は、導入したプロパティです。また、次のように変更しました。

function GetVCLFrameForm(Form: TCustomForm; DrawInTopForm: Boolean): IVCLFrameForm;
begin
  if Form.OleFormObject = nil then TOleForm.Create(Form, DrawInTopForm); 
  Result := Form.OleFormObject as IVCLFrameForm;
end;

残念ながら、お客様との合意により、ここに完全なソリューションを掲載することはできません。

于 2012-07-05T08:44:33.183 に答える