Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.02.2017, 18:20   #1
Fotal
Пользователь
 
Регистрация: 15.02.2017
Сообщений: 13
По умолчанию Извлечь выделенный текст в rtf формате RichEdit. Delphi7

Нужна помощь. Надо извлечь выделенный текст в какую-либо переменную, только чтобы формат текста сохранился (курсив, цвет, индекс ...). У меня есть код для извлечения всего текста:

Код:
//Извлекаем RTF текст из RichEdit
function GetRtfText(RichEdit : TRichEdit) : String;
var StringS : TStringStream;
begin
  //создаем пустую строку
  StringS := TStringStream.Create('');
  //запись текста из потока в переменную
  RichEdit.Lines.SaveToStream(StringS);
  //записываем результат
  Result := StringS.DataString;
  //очищаем StringS
  FreeAndNil(StringS);
end;
Но как сделать это для выделенного текста я не знаю.
Fotal вне форума Ответить с цитированием
Старый 17.02.2017, 19:15   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

CopyToClipboard
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 17.02.2017, 19:21   #3
Fotal
Пользователь
 
Регистрация: 15.02.2017
Сообщений: 13
По умолчанию

Если на чистоту, то я длаю буфер обмена как в Word. И я делаю CopyToClipBoard однако мне надо сохранить еще текст с форматом, чтобы когда пользователь кликнул на текст, который он скопировал 2 раза назад, вставился.
Fotal вне форума Ответить с цитированием
Старый 17.02.2017, 19:34   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

RichEdit.CopyToClipboard и копирует выделенный текст с сохранением форматирования в буфер обмена. Одно но - если нет выделенного, то буфер обмена не очищается. А как сохранить зависит от того куда сохраняешь. Есть PasteFromClipboard у того же ричэдита например. Ctrl+V не пробовал?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 17.02.2017 в 19:48.
Аватар вне форума Ответить с цитированием
Старый 17.02.2017, 19:48   #5
Fotal
Пользователь
 
Регистрация: 15.02.2017
Сообщений: 13
По умолчанию

Вы меня неправильно поняли. Я знаю что делает RichEdit.CopyToClipBoard, но как взять от туда текст в формате, если писать
s:=ClipBoard.asText;
то переменная 's' будет хранить в себе простой текст без формата.
ClipBoard.PasteFromClipBoard не помогает, т.к он вставляет текст в RichEdit, а мне нужно в переменную.
Fotal вне форума Ответить с цитированием
Старый 17.02.2017, 20:00   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В строковой переменной все форматирование потеряется. Сохранить/восстановить вроде в Stream можно и пример нашел, но не проверял. Может в XE и добавили такие функции

http://www.devsuperpage.com/search/A...sp?ArtID=61061
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 17.02.2017 в 20:02.
Аватар вне форума Ответить с цитированием
Старый 18.02.2017, 17:17   #7
Fotal
Пользователь
 
Регистрация: 15.02.2017
Сообщений: 13
По умолчанию

Не помогло.
Fotal вне форума Ответить с цитированием
Старый 18.02.2017, 18:42   #8
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Код:
By Peter Below (TeamB):

To extract and insert formatted
text you need to work with EM_STREAMIN and EM_STREAMOUT since the available
interface of the Delphi controls can only do that for the complete content of
a rich edit control. Add richedit to your Uses clause and play with the
following functions:

Type
  TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;

  TEditStream = record
    dwCookie: Longint;
    dwError: Longint;
    pfnCallback: TEditStreamCallBack;
  end;

function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
 cb: Longint; var pcb: Longint): DWORD; Stdcall;
var
  theStream: TStream;
  dataAvail: LongInt;
begin
  theStream := TStream(dwCookie);
  with theStream do begin
    dataAvail := Size - Position;
    Result := 0; {assume everything is ok}
    if dataAvail <= cb then begin
      pcb := Read(pbBuff^, dataAvail);
      if pcb <> dataAvail then {couldn't read req. amount of bytes}
        result := E_FAIL;
    end
    else begin
      pcb := Read(pbBuff^, cb);
      if pcb <> cb then
        result := E_FAIL;
    end;
  end;
end;


Function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;
 var
   theStream: TStream;
 begin
   theStream := TStream(dwCookie);

   with theStream do begin
     If cb > 0 Then
       pcb := Write(pbBuff^, cb);
     Result := 0;
   end;
 end;

Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(intoStream);
    dwError:= 0;
    pfnCallback:= EditStreamOutCallBack;
  end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION,
longint(@editstream));
End;

Procedure PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(sourceStream);
    dwError:= 0;
    pfnCallback:= EditStreamInCallBack;
  end;
  aRichedit.Perform( EM_STREAMIN, SF_RTF or SFF_SELECTION,
longint(@editstream));
End;

To copy the selection from one control to the other your do this:

Var
  aMemStream: TMemoryStream;
begin
  aMemStream := TMemoryStream.Create;
  try
    GetRTFSelection( richedit1, aMemStream );
    aMemStream.Position := 0;
    PutRTFSelection( richedit2, aMemStream );
  finally
    aMemStream.Free;
  end;
end;
Filka вне форума Ответить с цитированием
Старый 18.02.2017, 22:25   #9
Fotal
Пользователь
 
Регистрация: 15.02.2017
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Filka Посмотреть сообщение
Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
editstream: TEditStream;
Begin
With editstream Do Begin
dwCookie:= Longint(intoStream);
dwError:= 0;
pfnCallback:= EditStreamOutCallBack;
end;
aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION,
longint(@editstream));
End;
Спасибо, только одного не могу понять. Получается данные будут храниться в потоке intoStream, но он же у нас выступает как входной параметр, или для Stream не надо указывать var, т.к он ссылается на ячейку дин.памяти?

Все таки работать с потоками я не умею поэтому буду хранить RTF текст в переменной String;
Вот немного переделал.

Код:
function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;
var theStream: TStream;
begin
   theStream := TStream(dwCookie);
  with theStream do
    begin
      If cb > 0 Then
        pcb := Write(pbBuff^, cb);
      Result := 0;
    end;
end;

function GetRTFSelection( aRichEdit: TRichEdit):string;
var editstream: TEditStream; StringS:TStringStream;
begin
  StringS:=TStringStream.Create('');
  With editstream Do
    Begin
      dwCookie:= Longint(StringS);
      dwError:= 0;
      pfnCallback:= EditStreamOutCallBack;
    end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION,longint(@editstream));
  //записываем результат
  Result := StringS.DataString;
  //очищаем StringS
  FreeAndNil(StringS);
end;
Fotal вне форума Ответить с цитированием
Старый 06.12.2020, 03:30   #10
KBO
Форумчанин
 
Регистрация: 11.06.2010
Сообщений: 525
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
В строковой переменной все форматирование потеряется. Сохранить/восстановить вроде в Stream можно и пример нашел, но не проверял. Может в XE и добавили такие функции
Доброе время суток. форумчане.
(вопрос схожий)
Работаю с Delphi 10.2. и хочу уточнить:
Есть база на Firebird 3.0, и из нее заполняю шаблон в MS Word (c помощью OLE)

Код:
var
  AFindText, APasteText: widestring;
  TypeDos_Templs: variant;
...
TypeDos_Templs.Selection.Find.Text := AFindText;
TypeDos_Templs.Selection.Find.Replacement.Text := APasteText
...
до этого с форматированным текстом не сталкивался.
Вот пришлось, одно поле добавить и прикрутить к нему "RichEdit" (возникла необходимость в верхних/нижних индексах).

Исходя из вышеизложенного на сегодняшний день, если я хочу передать в MS Word, форматированный текст, то мне придется всетаки воспользоваться
или
- буфером обмена (я текст уже так передаю)
или
- потоком?
и какой вариант более правильный?

Другого варианта нет, получается?

Последний раз редактировалось KBO; 06.12.2020 в 03:40.
KBO вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
RichEdit. Центрировать выделенный текст по вертикали. victorixx Компоненты Delphi 6 17.09.2013 09:36
Программа, выполняющая поиск отказов в выписках (в формате RTF) и формирующая реестр отказников в формате XLS (на делфи) avtoritetbikov@mai Фриланс 5 08.11.2011 00:20
поиск отказов в выписках (в формате RTF) и формирующую реестр отказников в формате XLS avtoritetbikov@mai Фриланс 3 03.10.2011 09:03
Выделенный текст в RichEdit Andr Компоненты Delphi 1 20.08.2007 20:53
Текст в формате RTF Mikola Помощь студентам 2 10.08.2007 10:28