| Воронов 2004-05-18, 7:32 am |
| TOLEContainer
TOLEContainer - компонент, который нужно использовать во время
дизайна с осторожностью, поскольку вся информация о нем сохраняется в .DFM
файле. И если попытаться использовать встроенный (embedded) OLE-объект
большого размера, то при сохранении формы может возникнуть ошибка "Out of
resource".
I. Хранение OLE-объектов в базе данных
Использование технологии OLE для хранения информации в базе данных
оправдано, если эта информация неоднородна. Иногда возникает необходимость
одновременно сохранять в таблице и использовать в дальнейшем графические
изображения, документы в формате Microsoft Word, звук и тому подобное. К
сожалению, в стандартном наборе компонент отсутствует компонент вроде
TDbOleContainer. Однако, обойтись без него можно достаточно просто.
Для хранения OLE-объекта подойдет поле типа BLOB, а для работы с этим
объектом - существующий компонент TOLEContainer. Если предполагается
использовать таблицу на разных компьютерах, то OLE-объект нужно делать
встроенным (embedded) и следить за тем, чтобы присутствовали соответствующие
OLE-серверы.
Итак, сперва нужно заполнить таблицу:
{создание и инициализация OLE-объекта во время выполнения}
procedure TForm1.OLEInitClick(Sender: TObject);
var
OLE : TOLEContainer;
Info : Pointer;
begin
{создание OLE-контейнера}
OLE:=TOLEContainer.Create(Self);
OLE.Name:='Temp_OLE';
OLE.Parent:=Self;
{вызов диалога инициализации OLE-объекта}
if InsertOLEObjectDlg(Self, 0, Info) then begin
OLE.PInitInfo := Info;
ReleaseOLEInitInfo(Info);
end
else
OLE.Free;
end;
{уничтожение OLE-контейнера}
procedure TForm1.OLEFreeClick(Sender: TObject);
begin
FindComponent('Temp_OLE').Free;
end;
{сохранение OLE-объекта в BLOB поле}
procedure TForm1.InsertClick(Sender: TObject);
var
OLE : TOLEContainer;
TBS : TBlobStream;
begin
OLE:=FindComponent('Temp_OLE') as TOLEContainer;
if Assigned(OLE) then
with OLE do begin
{добавляем в таблицу новую запись}
Table1.Insert;
{создаем поток, связанный с BLOB полем}
TBS:=TBlobStream.Create(Table1.FieldByName('OLE') as
TBLOBField, bmReadWrite);
{сохраняем OLE-объект в поток}
SaveToStream(TBS as TStream);
{уничтожаем поток}
TBS.Free;
Exit;
end;
end;
{завершаем редактирование таблицы}
procedure TForm1.PostClick(Sender: TObject);
begin
if Table1.State <> dsBrowse then Table1.Post;
end;
Вторая часть проблемы - чтение OLE-объекта из таблицы и обновление
информации при его модификации. Здесь можно предложить динамически создавать
OLE-контейнер и считывать OLE-объект из потока, связанного с BLOB полем. И
делать это каждый раз при переходе на новую запись (перехватывать для
DataSource событие OnDataChange). Либо вытаскивать информацию по запросу
пользователя, а уничтожать OLE-контейнер при переходе на новую запись.
{считывание OLE-объекта из таблицы}
procedure TForm1.ViewClick(Sender: TObject);
var
OLE : TOLEContainer;
TBS : TBLOBStream;
begin
{создаем OLE-контейнер}
OLE:=TOLEContainer.Create(Self);
OLE.Parent:=Self;
OLE.Name:='Temp_OLE';
{создаем поток для BLOB поля}
TBS:=TBLOBStream.Create(Table1.FieldByName('OLE') as
TBLOBField, bmRead);
{инициализируем OLE-объект}
OLE.LoadFromStream(TBS as TStream);
{уничтожаем поток}
TBS.Free;
end;
{сохранение модифицированного OLE-объекта}
procedure TForm1.SaveClick(Sender: TObject);
var
TBS : TBLOBStream;
OLE : TOLEContainer;
begin
{находим объект}
OLE:=FindComponent('Temp_OLE') as TOLEContainer;
if Assigned(OLE) then
with OLE do
{сохраняем, если был модифицирован}
if Modified then begin
Table1.Edit;
{очищаем BLOB поле}
TBLOBField(Table1.FieldByName('OLE')).Clear;
{создаем поток}
TBS:= TBlobStream.Create(Table1.FieldByName('OLE') as
TBLOBField, bmReadWrite);
{сохраняем объект}
SaveToStream(TBS as TStream);
{уничтожаем поток}
TBS.Free;
Table1.Post;
end;
end;
{уничтожение OLE-контенера при переходе на другую запись}
procedure TForm1.DataSource1DataChange(Sender: TObject;
Field: TField);
begin
if Table1.State = dsBrowse then
FindComponent('Temp_OLE').Free;
end;
В примерах выше предполагается наличие таблицы с BLOB полем, которое
называется "OLE".
"news.tpi.pl" <borsuk_@poczta.onet.pl___> сообщил/сообщила в новостях
следующее: news:c88i53$fdf$1@atlantis.news.tpi.pl...
> I suppose it's silly question, but i need to know how to exit windows???
>
>
|