How to use Word in TOleContainer in TForm layout correctly?

I wonder what is the way to implement and manage MS Word in TForm, a layout? Currently, I (1) have put two TPanel on TForm. alBottom TPanel has one TButton, and alClient TPanel has alNone TOleContainer. (2) customize the layout in the TMainForm.FormCreate event handler.

The problem is that MS Word likes to occupy the entire space of its parent form. Only the fourth method, as shown below, gives an acceptable layout. Based on trial and error, it seems necessary to use a subform instead of TPanel to host the TOleContainer. (It also seems like Windows.SetParent seems necessary.) I wonder if the subformation is suitable?

PS: Delphi XE, Word 2010, Windows 7

PS: web pages related to "hosting of external applications":

Website Binh Ly

Deborah website

How to copy to another application and display it in delphi form

Repeat TOleContainer

Open Word document in delphi?

Delphi and Word (SimpChn)

PS: web pages associated with "Form in Panel (sub form form)":

How to make a transparent form inside the panel?

Delphi - OleContainer - PowerPoint - AutoPlay

FreePascal / Lazarus MultiDoc

TForm in the panel

How to create a delphi form containing several child forms that can be moved / resized and shown activated

code example

 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. 
+6
source share
1 answer

A subform is the right way to do this. We used this approach in a production environment, and it worked. We placed our "under" form in the panel. However, we modified TOleContainer and TOleForm with the flag whether to use the parent form or the topmost form:

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

Where FDrawInTopForm is the property we introduced. We also changed:

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

Unfortunately, due to agreements with the client, I cannot post the full solution here.

+1
source

Source: https://habr.com/ru/post/919623/


All Articles