Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.03.24;
Скачать: CL | DM;

Вниз

Clipboard -> MS SQL   Найти похожие ветки 

 
Shirson ©   (2003-03-06 07:46) [0]

Возник вопрос. Как данные из клипборда перекинуть в SQL?
В клипборде хранится кусок вордовского файла. Его, as is, нужно закинуть в таблицу SQL. В каком виде он будет лежать в таблице - совершенно не критично, главное, чтобы потом его можно было изъять и вставить в вордовский документ. С сохранением форматирования, болдов, италиков и пр.
Вот тут и возник затык - как взять данные из клипборда, чтобы сохранилось форматирование? В идеале лучше получать строку байт.
Посоветуйте, плз.
Это как вариант.
Общая задача выглядит так:
Есть большой вордовский файл с кучей заметок, каждая отформатирована и приведена в божеский вид. Необходимо раздербанить этот файл и каждую заметку закинуть в SQL с сохранением божеского вида. Чтобы потом можно было из SQL покидать заметки обратно в вордовский файл.


 
Дмитрий Баранов ©   (2003-03-06 10:18) [1]

Кусок кода привести не смогу, а общий принцип -
IDataObject
IDataObject::GetData при STGMEDIUM.tymed = TYMED_ISTREAM - сохранение клипборда в поток - IStream,
затем полученный поток можно писать сразу в ADODB.Field.

Можно глянуть про COleDataObject в MSDN - класс-обертка IDataObject.


 
Shirson ©   (2003-03-07 06:25) [2]

Спасибо, попробую


 
Shirson ©   (2003-03-07 11:37) [3]

Что-то у меня соображайка не работает... С такими вещами никогда не сталкивался, поэтому соображайка кончилась :)
Делаю так:
var
dataobject:idataobject;
frm:TFormatEtc;
med:TStgMedium;
res:HResult;
istr:TOleStream;
begin
istr:=TOleStream.Create(nil);
med.tymed:=TYMED_ISTREAM;
med.stm:=istr;
frm.tymed:=TYMED_ISTREAM;
res:=dataobject.GetData(frm,med);


На последней строке вываливается ошибка Access violation.
Idataobject создавать нужно? А как?


 
Дмитрий Баранов ©   (2003-03-07 14:16) [4]

Ну... это же интерфейс, а он абстрактен, и реализацию его методов нужно писать самому, унаследовав класс от оного :-) ( муторно, но надо :-)
type
TClipboardClass = class(TObject, IDataObject)
// сюда - методы
end;

ищем в исходниках описание IDataObject, ctrl+c, вставляем сюда методы, жмем ctrl+shift+c, IDE генерит болванки реализаций, а дальше надо примеры поискать в сети - я с эти интерфесом возился, когда Drag-Drop текста из ворда надо было сделать. Поищи по IDropTarget, IDropSource, IDataObject, Drag Drop.


 
Дмитрий Баранов ©   (2003-03-07 14:19) [5]

..не от TObject, а от TInterfacedObject (про методы IUnknown забыл...)


 
Дмитрий Баранов ©   (2003-03-07 14:22) [6]

Млин... :-)

WINOLEAPI OleGetClipboard(
IDataObject ** ppDataObj //Address of output variable that
// receives the IDataObject interface
// pointer
);

Аллес. Все вышенаписанное зачеркиваем.


 
Shirson ©   (2003-03-11 12:35) [7]

Дмитрий, не вели казнить, вели слово молвить :)
Я просто с интерфейсами и клипбордами дела никогда не имел, поэтому и мучаю и себя и других :)

Вот до чего дорылся:

var
DataObject: IDataObject;
FormatEtc: TFormatEtc;
Medium: TStgMedium;
fieldstream:tstream;
Hres:hresult;
begin
hres:=olegetclipboard(dataobject);
FormatEtc.cfFormat := ; // Тут что должно стоять? CF_TEXT явно не в тему.
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_CONTENT;
FormatEtc.lIndex := -1;
FormatEtc.tymed := TYMED_ISTREAM; // Правильно?
if Succeeded(DataObject.GetData(FormatEtc, Medium)) then form1.Caption:="Ok"; // Верно?

А вот дальше затык :(
Как с medium забрать поток?
Как забранный поток записать в таблицу?
FieldStream:=adoquery1.CreateBlobStream(ADOQuery1.FieldByName("Doc"),bmwrite); // Верное направление?

Сорри, что достаю, но нужно позарез :)


 
REA ©   (2003-03-11 12:43) [8]

А не проще по-старинке - взять блок как формат ворда? Сорри если глупость сказанул...


 
Shirson ©   (2003-03-11 13:01) [9]

>REA
А поподробнее?


 
REA ©   (2003-03-11 13:16) [10]

Ну типа как в примере:
var
MyHandle: THandle;
TextPtr: PChar;
MyString: string;
begin
ClipBoard.Open;
try
MyHandle := Clipboard.GetAsHandle(CF_Какой-то вордовый формат);
TextPtr := GlobalLock(MyHandle);
MyString := StrPas(TextPtr);
GlobalUnlock(MyHandle);
finally
Clipboard.Close;
end;
end;


 
Shirson ©   (2003-03-11 13:35) [11]

"CF_Какой-то вордовый формат" это какой? :)
И форматирование при таком способе сохраняется?


 
Дмитрий Баранов ©   (2003-03-11 14:27) [12]

100%-правильное направление я дал, но времени нету совершенно :-)
Попробуй получить enumerator форматов, которые поддерживает текущий кусок клипборда:

интерфейс IEnumFormatETC
метод IDataObject::EnumFormatEtc

и поэкспериментировать с ними.

Данные забрать из STGMEDIUM можно с помощью методов интерфейса IStream (Seek, Read, CopyTo), куда угодно, хоть в другой поток, зоть в массив


 
REA ©   (2003-03-11 14:29) [13]

>"CF_Какой-то вордовый формат" это какой? :)
Наверно где-то в документации по ворду это есть.

При таком способе можно (вероятно) достать данные, в том виде, в котором их Word держит в клипборде в своем формате. Что с ними делать дальше, понятия не имею, кроме как засунуть обратно в clipboard. Наверно можно достать данные и в других форматах, если ворд поддерживает их (RTF в частности), но не все можно в RTF засунуть, что есть в ворде.


 
Баранов   (2003-03-12 00:25) [14]

(*
раздраконил я этот клипборд к чертям. Оказалось, что Word хранит
в клибоде данные в десятке форматов, выбирай нужный по
FORMATETC.cfFormat

Эта процедура получает все форматы,
все содержимое клипборда и сохраняет их содержимое в файлах корне С.
Выбирай, что тебе нужно :-) и толкай в базу (хоть все сразу в разные поля)
Вышло, что фоматирование ворд хранит в XHTML формате
Обнаружены также ANSI-формат,
UNICODE, RTF, и какие-то непонятные бинарики.

Как запихать в рекордсет:
у ADODB.Field есть методы GetChunk и AppendChunk,
дальше дело техники - записать данные из буфера в поле.

равно как и запихать данные обратно в буфер из базы данных

*)
procedure TForm1.Button1Click(Sender: TObject);
var pObj : IDataObject;
pEnumFormatEtc : IEnumFormatEtc;
iFetched : longint;
iRead : longint;
m_FormatEtc : TFormatEtc;
m_Medium : STGMEDIUM;
m_Global : HGLOBAL;
pStream : IStream;
m_stat : STATSTG;
buff : array [0..1024] of byte;
pBuff : PByte;
F : File of byte;
begin
try
OleCheck(OleGetClipboard(pObj));
OleCheck(pObj.EnumFormatEtc(1, pEnumFormatEtc));
OleCheck(pEnumFormatEtc.Reset);
while ( iFetched > 0) do begin
OleCheck(pEnumFormatEtc.Next(1, m_FormatEtc, @iFetched));
pObj.GetData(m_FormatEtc, m_Medium);
if (m_Medium.tymed = TYMED_HGLOBAL) then begin
m_Global := m_Medium.hGlobal;
GlobalLock(m_Global);
OleCheck(CreateStreamOnHGlobal(m_Global, true, pStream));
OleCheck(pStream.Stat(m_stat, STATFLAG_DEFAULT));
GetMem(pBuff, m_stat.cbSize);
OleCheck(pStream.Read(pBuff, m_stat.cbSize, @iRead));
AssignFile(F, "C:\" + IntToStr(m_FormatEtc.cfFormat) + ".cpb");
Rewrite(F);
BlockWrite(F, pBuff^, m_stat.cbSize);
CloseFile(F);
FreeMem(pBuff, m_stat.cbSize);
GlobalUnlock(m_Global);
end
end
except
On E: Exception do ShowMessage(E.Message);
end;
end;


 
Shirson ©   (2003-03-12 08:49) [15]


Дмитрий, с меня пиво. Если ты из Алматы, хоть сейчас. Если из Москвы - чуть попозжа, когда кент поедет :)
Если из какого другого города - говори, найдём пути :)

Спасибо огромное :)



Страницы: 1 вся ветка

Текущий архив: 2003.03.24;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.028 c
7-76691
Инга
2003-01-30 18:45
2003.03.24
Как можно перехватить нажатие Ctrl-Alt-Del


14-76648
ZORRO
2003-03-07 20:44
2003.03.24
DELPHI CITY


14-76582
DiamondShark
2003-03-06 11:21
2003.03.24
Неприличные слова


14-76631
Jeer
2003-03-06 12:38
2003.03.24
Дамы ! С Праздником Вас


3-76363
Соловьев
2003-03-06 13:03
2003.03.24
Как ускорить поиск?