Конференция "Corba" » Как выделение документа Ворд записать в поток без буфера обмена?
 
  • Darrin (17.09.08 16:05) [0]
    Доброго времени суток.
    Столкнулся с проблемой, что из вордового документа (через OLE) получается получить текст из выделенной области только с помощью буфера обмена. Текст документа целиком можно получить через интерфейс IDataObject

    var
      DataObject: IDataObject;
      RTFFormat: TFormatEtc;
      ReturnData: TStgMedium;
      Buffer: PChar;
      WordDoc: _Document;
      WordApp: _Application;
    begin
      Result := '';
      try
        GetActiveOleObject('Word.Application').QueryInterface(_Application, WordApp);
      except
        ShowMessage('Error: MSWord is not running');
        Exit;
      end;
      if (WordApp <> nil) then
        try
          WordDoc := WordApp.ActiveDocument;
          WordDoc.QueryInterface(IDataObject, DataObject);
          if GetRTFFormat(DataObject, RTFFormat) then
          begin
            OleCheck(DataObject.GetData(RTFFormat, ReturnData));
            //RTF is passed through global memory
           Buffer := GlobalLock(ReturnData.hglobal);
            //Buffer is a pointer to the RTF text
           Result := StrPas(Buffer);
            GlobalUnlock(ReturnData.hglobal);
            ReleaseStgMedium(ReturnData);
          end;
        except
          // Error occured...
       end;
    end;


    Полный пример тут: http://www.delphisources.ru/pages/faq/base/get_rtf_from_msword.html

    Мне же необходимо выдёргивать из документа кусочки текста. Пробовал запрашивать IDataObject у всех возможных объектов документа, но ни один элемент не поддерживает этого интерфейса.
    Может кто знает, как выдернуть текст из выделенной области, минуя буфер обмена?
    Заранее, спасибо.
  • Сергей М. © (18.09.08 12:57) [1]
    Ты сейчас упадешь со стула, увидев в какие дебри ты полез и как на самом деле это просто:

    StringList.Text := WordApp.Selection.Text;
    StringList.SaveToStream(MyStream);

  • Darrin (18.09.08 17:14) [2]
    Я не правильно выразился. Нужно получить не просто текст, а полную копию того, что есть в выделении. WordApp.Selection.Text возвращает строку без форматирования. Максимум, переносы строки. А выделение может содержать таблицы, текст с форматирование, что угодно. При копировании выделения в буфер обмена (WordApp.Selection.Copy), кроме неформатироннного текста попадает ещё и структура полностью содержащая информацию об объетах выделенной области. Что позволяет выполнить WordApp.Selection.Paste и получить полную копию выделения. Мнеже необходио выполнить эту процедуру только без участия буфера обмена. Т.е. считать выделенную область, сохранить её где-то в памяти моего приложения, и вставить в нужное место документа.
  • Сергей М. © (18.09.08 20:00) [3]

    > Я не правильно выразился


    Вследующий раз выражайся правильно.

    И изволь выражаться по-русски - "не правильно", да будет тебе известно, в данном контексте пишется слитно.


    > считать выделенную область, сохранить её где-то в памяти
    > моего приложения, и вставить в нужное место документа

    А зачем тут стрим ?
  • Darrin (19.09.08 18:30) [4]
    Давай не будем спорить о правописании и переходить на личности.
    стрим - это наибоее простой и оптимальный способ хранения двоичных данных любого формата, буть то текст или что либо другое.
  • Сергей М. © (19.09.08 19:19) [5]

    > хранения


    Зачем тебе что-там "хранить" ?

    Ведь задача у тебя, насколько ты"правильно выразился", - вставить копию объекта-выделения !

    Ну и зачем тут стрим, спрашивается ?

    Некий метод Src.Copy получает объект-копию.
    И тут же некий метод Dst.Paste(Копия) реализует вставку.

    Зачем тут стрим ?
  • Darrin (22.09.08 12:22) [6]
    >Зачем тебе что-там "хранить" ?
    Вставить скопированную область необходимо не сразу после её копирования, а через неопределённое время. В течении этого неопределённого времени содержимое буфера обмена может изменится.

    > Некий метод Src.Copy получает объект-копию.
    > И тут же некий метод Dst.Paste(Копия) реализует вставку.

    Применительно в объектам Ворда Selection и Range:
    метод Copy копирует выделенную область с буфер обмена.
    метод Paste вставляет в выделенную область значение из буфера обмена.
    Я был бы очень рад, если бы у одного из них был метод Dst.Paste(Копия)
  • Сергей М. © (22.09.08 12:53) [7]

    > В течении этого неопределённого времени содержимое буфера
    > обмена может изменится


    Можно поступить так - после вызова Copy открыть клипборд и сохранить в какой-либо буфер данные формата CF_METAFILE. В нужный момент восстановить в клипборде  сохраненные ранее в буфере CF_METAFILE-данные, после чего тут же выполнить Paste
  • Darrin (23.09.08 10:21) [8]
    Именно так я и делаю в данный момент, но хотелось бы не использовать буфер вовсе. Отпала бы необходимость обработки ошибок доступа к буферу обмена (при копировании выделения в буфер, буфер может быть кем-то занят, а такое бывает часто, если открыты другие приложения Офиса)
  • Сергей М. © (23.09.08 10:50) [9]
    Тогда попробуй воспользоваться св-вом Selection.FormattedText
  • Darrin (25.09.08 16:46) [10]
    Selection.FormattedText: Range - это, ссылка на область документа. С помощью этого свойства можно скопировать область документа:
    var ARange: Range;
    ...
     ARange := WordApplication1.Selection.FormattedText.Duplicate;
    ..
     WordApplication1.Selection.FormattedText := ARange;


    , но должен быть источник, откуда производится копирование. Если же между запоминаем обрасти и копированием в области ARange были произведены изменения, то копия будет содержать все изменения поизведённые в области ARange до копирования.
  • qwasttt © (08.11.10 09:18) [11]
    Доброго дня
    помогите с решением проблемы
    из Вордовского документа (Картинки, формулы и прочие объекты ) загрузить в БД Парадокс
 
Конференция "Corba" » Как выделение документа Ворд записать в поток без буфера обмена?
Есть новые Нет новых   [134427   +34][b:0][p:0.002]