I wonder what is the suggested way to embed and control MS Word in a TForm, layout-wise? Currently, I (1) put two TPanel on TForm. The alBottom
TPanel has one TButton, and the alClient
TPanel has a alNone
TOleContainer. (2) set up the layout in TMainForm.FormCreate event handler.
The problem is MS Word likes to take up all the space of its parent form. Only the fourth way as shown below seems to give acceptable layout. Based on trial-and-error, it seems necessary to use a sub-form instead of TPanel to host TOleContainer. (Also, Windows.SetParent seems necessary.) I wonder whether a sub-form is the correct way to go?
PS: Delphi XE, Word 2010, Windows 7
PS: web pages related to "hosting external applications":
How to shell to another app and have it appear in a delphi form
PS: web pages related to "Form in Panel (sub-form)":
how to make a transparent form inside Panel?
Delphi - OleContainer - PowerPoint - AutoPlay
sample code
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.