Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  16:47[Войти] | [Зарегистрироваться]

Блокирование документов при использовании TOleContainer.

Дамир
дата публикации 29-10-2007 06:33

Блокирование документов при использовании TOleContainer.

Всем известно, что при использовании 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 я не исследовал, поэтому, возможно есть другие, более красивые решения.




Смотрите также материалы по темам:
[TOleContainer] [Использование OLE]

 Обсуждение материала [ 07-10-2009 23:57 ] 2 сообщения
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования