6.4.2 Внедрение и связывание
Теперь рассмотрим основные приемы использования OLE в C++Builder. На странице System библиотеки визуальных компонентов имеется контейнер OLE OleContainer — компонент, обеспечивающий внедрение и связывание. Давайте посмотрим его возможности сначала на очень простом примере. Разместите на форме контейнер OleContainer, компонент главного меню MainMenu, диалоги OpenDia-log и SaveDialog. Можно также разместить панель и на ней быстрые кнопки, дублирующие основные команды меню. Но меню, как мы увидим ниже, должно быть обязательно.
Панель, если вы ее ввели, выравнивается по верху формы (Align = alTop), a контейнер должен занимать всю оставшуюся площадь формы (Align, = alClient). Пример такого приложения приведен на рис. 6.3.
В MainMenu введите меню Объект и в нем разделы Новый, Открыть, Сохранить, Закрыть. Назовите объекты этих разделов MNew, MOpen, MSave и MClose.
Установите в диалогах в свойстве Filter: «объекты OLE | *.ole» и «все файлы | *.*». Установите также в диалогах расширение по умолчанию в свойстве DefaultExt равным ole.
Теперь перейдем собственно к программированию. Давайте введем в определении класса формы глобальную переменную Fname, в которой будет храниться имя файла объекта OLE:
AnsiString FName; '
Процедура, соответствующая разделу меню Новый, может иметь вид:
{ • :. if (OleContainerl->InsertObjectDialog()) FName = ""; '
} ''.'..
Вызываемый этим оператором метод InsertObjectDialog осуществляет обращение к стандартному окну Windows Insert Object (вставка объекта), в котором пользователь может указать тип вставляемого объекта, инициализирует объект OLE и Загружает его в контейнер OleContftinerl. Работу с окном Вставка объекта мы рассмотрим несколько позднее, а пока продолжим создание приложения.
Процедура, соответствующая разделу меню Закрыть, может иметь вид:
void _fastcall .TForml.: ;MCloseClick(TOb3ect *Sender)
< . - '.'..•
01eContainerl->DestroyObject(); }
Эта процедура разрушает объект в контейнере OLE.
Процедура, соответствующая разделу меню Сохранить, может иметь вид:
void_fastcall TForml::MSaveClick(TObject ^Sender) { •••••.' if (FName == "") , . if (SaveDialogl->Execute()}
FName = SaveDialogl->FileName; else return;
OleContainerl->SaveToFiie(ChangeFileExt(FName, ".ole")) ; } ' •
Если имя файла не задано, то вызывается диалог Сохранить как (SaveDialogl), с помощью которого пользователь задает имя файла. Затем методом SaveTbFile объект сохраняется в файле. При этом во избежание ошибок расширение файла принудительно заменяется на .ole с помощью функции ChangeFileExt, изменяющей расширение файла (см. главу 15 раздел 15.5.5).
Процедура, соответствующая разделу меню Открыть, может иметь вид:
void_fastcall TForml::MOpenClick(TObject *Sender) {
if (OpenDialogl->Execute())
{ , 01eContainerl->LoadFromFile(OpenDialogl->FileName); FName = OpenDialogl->FileName; OleContainerl->Repaint(); } } .
Она обычным образом вызывает диалоговое окно, в котором пользователь выбирает открываемый файл. Затем объект, соответствующий этому файлу, загружается в контейнер методом LoadFromFile. Имя файла запоминается в переменной FName. Последний оператор методом Repaint перерисовывает окно контейнера, чтобы в нем немедленно отобразился открытый объект.
Теперь посмотрим, как работает наше приложение. Запустите его на выполнение и выполните команду Новый. Перед вами откроется окно Вставка объекта (Insert Object^, представленное на рис. 6.4. В этом окне вам предоставляются две возможности: создание нового объекта OLE (радиокнопка Создать новый), или создать объект из имеющегося файла (радиокнопка Создать из файла).
Рассмотрим сначала первую возможность. А этом случае в окне Тип объекта вы должны указать тип вставляемого в контейнер объекта. Это может быть документ Word, лист Excel, объект звукозаписи, точечный рисунок (как на рис, 6.4) и т.п. Правда, к сожалению, надо отметить, что не любой тип объекта и не в любой версии Windows может быть вставлен. Так что с переносимостью подобных приложе^ ний могут возникнуть проблемы. Если вставка не получится, вам будет выдано соответствующее сообщение.
После того, как вы выбрали тип объекта и щелкнули на ОК, в контейнере OLE вашего приложения отобразится вид объекта по умолчанию. Этот вид зависит от типа объекта. Возможно, в первый момент вы вообще ничего не увидите. Сделайте двойной щелчок на контейнере, вызывая тем самым программу, обслуживающую объект этого типа. Вы увидите, что ваше приложение чудесным образом преобразится. В него встроится соответствующая программа вместе со своими инструментальными панелями и меню. На рис. 6.5 вы видите встроенную программу Microsoft Paint, обслуживающую объекты битовых мйтриц — точечные рисунки. Вы можете нарисовать какое-то свое изображение или с помощью команды ее меню Правка | Вставить из файла открыть какой-то файл с битовой матрицей. На рис. 6.5, например, открыт файл, расположенный в каталоге \program file$\Common Files\Borland Shared\lmages\Splash\16Color\athena.bmp. Далее вы может редактировать загруженное изображение (цравда, надеюсь, у вас не поднимется рука редактировать показанное на рис. 6.5 прекрасное фирменное изображение Borland).
Обратите внимание на то, что ваша инструментальная панель сохранилась на экране и после загрузки объекта и начала работы с ним. И, главное, заметьте, что не все разделы меню программы Microsoft Paint встроились в ваше приложение. Нет первого меню — Файл, в котором содержатся команды открытия и сохранения файлов. Это не случайно, так как далее будет показано, что сохранение объекта OLE отличается от сохранения файла изображения. Как вы можете видеть на рис. 6.5^ вместо меню Файл, имеющегося в Microsoft Paint, встроилось меню Объект вашего приложения, в котором имеются соответствующие команды открытия и закрытия файла. Именно ради этого мы и делали в своем приложении меню.
Мы рассмотрели одну из возможностей создания в вашем приложении объекта OLE. Теперь давайте вернемся к окну рис. 6.4 и рассмотрим другие возможности. Выполните опять команду Новый вашего приложения и в окне рис. 6.4 выберите радиокнопку Создать из файла (Create from File). ЛШом случае вы можете создать объект OLE на основе имеющегося файла. При этом диалоговое окно изменит свой вид (см. рис 6.6). В нем вы можете с помощью кнопки Обзор выбрать какой-нибудь файл, например, тот же файл athena.bmp, который использован в предыдущем примере. Обратите внимание на очень важный индикатор Связь (Link). Пока не устанавливайте этот индикатор, а просто нажмите ОК.
В контейнер вашего приложения загрузится содержимое файла (рис. 6.7). Вы создали в своем приложении внедренный (но не связанный) объект OLE. Если вы хотите вызвать программу, обслуживающую этот объект (в нашем примере — Microsoft Paint), сделайте на нем двойной щелчок. Вы увидите ту же картину, с которой уже знакомы по рис. 6.5 — программа Microsoft Paint встроится в ваше приложение.
Теперь остановимся на сохранении объекта. Бели вы выполните команду вашего приложения Сохранить, то с помощью обычного диалога сохранения можете записать объект в нужный вам каталог. Тем самым вы создадите файл, содержащий внедренный объект OLE. В дальнейшем вы можете открыть его командой Открыть вашего приложения. Это абсолютно автономный объект, никак не связанный с исходным файлом, из которого ои был создан. Но открыть его можно только как объект OLE. Если вы..попробуете открыть его, например, программой Microsoft Paint, вы потерпите неудачу, так как Microsoft Paint не поймет формата этого файла.,
Теперь попробуйте создать внедренный и связанный документ. Выполните опять команду Новый вашего приложения, в диалоговом окне Вставка объекта, представленном на рис. 6.4, опять выберите радиокнопку Создать из файла (Create from File), затем в окне рис. 6.6 выберите какой-нибудь файл, но на этот раз установите индикатор Связь (Link). После щелчка на ОК в окне вашего приложения снова появится выбранный вами объект документа. Вы опять можете сохранить этот объект командой Сохранить. Но теперь документ в вашем объекте не просто внедрен, а и связан с исходным файлом. Это означает, что все изменения в исходном файле отразятся в вашем объекте и наоборот. Кроме того изменяется и взаимодействие вашего приложения с документом, Если вы сделаете двойной щелчок на объекте в вашем приложении, тр откроется отдельное, полноценное окно программы, обрабатывающей ваш объект, например, Microsoft Paint, с загруженным в него доку-
ментом. Вы можете что-то изменить в нем, напечатать его, сохранить. Как только он будет сохранен, в вашем приложении отразятся введенные изменения.
Вы создали очень простое приложение, использующее OLE. Его можно усовершенствовать, добавив в меню еще несколько разделов. Один из них — Открыть файл. В отличие от рассмотренного ранее раздела, открывающего объект OLE, в данном разделе можно создавать новый объект'на основе какого-то существующего файла документа. Делается это методом CreateObjectFromFile:
void CreateObjectFromFile(AnsiString FileName, bool Iconic);
Аргумент FileName определяет имя открываемого файла. Второй аргумент функции Iconic, значение которого обычно задается равным false, показывает, что объект отображается в том виде, в каком он содержится в исходном файле. Если задать этот аргумент, равным true, то объект будет отображаться в виде пиктограммы.
Таким образом, в вашем приложении обработчик команды Открыть файл может иметь вид:
void_fastcall TForml::MOpenFClick(TObject «Sender) .{ ••''•' if (OpenDialogl->Execute()) {
OleContainerl-S-CreateObjectFromFile(OpenDialogl->FileName, false); FName = OpenDialogl->FileName; 01eContainerl->Repa'int () ; } , ' . . }
Выполнение этой команды эквивалентно описанному ранее созданию внедренного объекта OLE из файла, но исключает необходимость пользователю работать с окнами рис. 6.4 и 6.6.
Имеется также аналогичный метод CreateLinkToFile, позволяющий создавать внедренный и связанный объект:
void CreateLinkToFile(const AnsiString FileName, bool Iconic);
Можете воспользоваться им для включения в ваше меню и такого раздела.
Еще один раздел, который можно добавить в меню вашего приложения — Сохранить файл. В отличие от рассмотренного ранее раздела, сохраняющего в файле объект OLE, в данном разделе можно сохранять документ, содержащийся в объекте, в его натуральном виде. Это можно сделать оператором, использующим функцию SaveAsDocument:
01eContainerl->SaveAsDocument(FName);
Функции CreateObjectFromFile, CreateLinkToFile и SaveAsDocument позволяют построить фактически универсальный редактор текстовых, графических, музыкальных и других файлов.