Блокування документів при використанні TOleContainer., Різне, Програмування, статті

Автор: Дамір, Королівство Delphi


Всім відомо, що при використанні OleContainerа блокуються раніше відкриті документи, і неможливо з ними нічого зробити. Недавно постало питання: добре б мати можливість якось розблокувати ці документи. Я за звичкою поліз в VCL і ось що знайшов: В об’єкта TOleContainer є внутрішня змінна FDocView, яка вказує на інтерфейс IOleDocumentView і ініціалізує на початку активізації OleContainerа:

TOleContainer = class(TCustomControl, IUnknown, IOleClientSite,
IOleInPlaceSite, IAdviseSink, IOleDocumentSite, IOleUIObjInfo)
private
FDocView: IOleDocumentView;

У свою чергу, у інтерфейсу IOleDocumentView є метод Show (fShow: BOOL):

IOleDocumentView = interface(IUnknown)
[“{b722bcc6-4e68-101b-a2bc-00aa00404770}”]
function Show(fShow: BOOL):HResult; stdcall;

Для “пожвавлення” заблокованих документів, досить викликати цей метод з параметром “false”. Додаємо процедуру (або функцію з можливістю обробки помилок, кому як більше подобається) ShowView (fShow : Boolean) в TOleContainer:

public procedure ShowView (fShow: boolean); / / Додаємо нову процедуру

і реалізацію:

procedure TOleContainer.ShowView(fShow : boolean);
begin
if Pointer(FDocView) <> nil then
FDocView.Show(fShow);
end;

Для демонстрації роботи створимо MDI додаток. Нехай дочірнє вікно містить компонент OleContainer1 (Модуль, де знаходиться новий клас TOleContainer я назвав OleCtnrs_):

unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtnrs_, StdCtrls, ExtCtrls, ExcelXP, ActiveX;
type
TForm2 = class(TForm) //ChildForm
procedure FormCreate(Sender: TObject);
private
OleContainer1: TOleContainer;
public
{ Public declarations }
procedure OpenFile(FileName : string);
procedure DoDocShow;
procedure DoHideView;
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
{Тут відкриваємо документ}
procedure TForm2.OpenFile(FileName : string);
begin
OleContainer1.CreateObjectFromFile(FileName, false);
DoDocShow;
end;
{Тут викликаємо ShowView}
procedure TForm2.DoHideView;
begin
OleContainer1.ShowView(false);
end;
{Тут знову активізуємо OleContainer}
procedure TForm2.DoDocShow;
begin
OleContainer1.DoVerb(ovShow);
end;
{Тут створюємо новий об’єкт OleContainer}
procedure TForm2.FormCreate(Sender: TObject);
begin
OleContainer1 := TOleContainer.Create(Self);
OleContainer1.Parent := Self;
OleContainer1.Align := alClient
end;
end.

Далі пишемо батьківське вікно:

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, OleCtnrs;
type
TForm1 = class(TForm) //MDIForm GroupBox1: TGroupBox; / / (Align: = allBottom) TGroupBox, тому, що він не перекривається дочірнім вікном. Button1: TButton; / / Ставимо кнопку на GroupBox1
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject); {Випробував всякі події, зупинився на цих}
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMKillFocus(var Message: TWMSetFocus); message WM_KILLFOCUS;
private
{ Private declarations }
function GetViewActive : boolean;
public
{ Public declarations }
property ViewActive : boolean read GetViewActive;
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
function TForm1.GetViewActive : boolean;
begin
result := MDIChildCount <> 0;
end;
procedure TForm1.WMKillFocus(var Message: TWMSetFocus);
begin
if ViewActive then
begin
TForm2(MDIChildren[0]).DoDocShow;
end;
inherited;
end;
procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
if ViewActive then
begin
TForm2(MDIChildren[0]).DoHideView;
end;
inherited;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
with TForm2.Create(Application) do
begin
Visible := true;
OpenFile(OpenDialog1.FileName);
end;
end;
end;
end.

Програма працює наступним чином: Відкривається, наприклад, документ Excel. Потім запускається програма і відкривається інший документ Excel, але вже всередині OleContainerа. При перемиканні між Excelем і програмою з’являється можливість роботи з цими документами.


Програма працює зі скрипом і скреготом, але дозволяє передавати фокус заблокованим документам. Може комусь і знадобиться. Решта методів інтерфейсу IOleDocumentView я не досліджував, тому, можливо є інші, більш красиві рішення.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*