Форум: "Основная";
Текущий архив: 2003.03.24;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.009 c