Используя TRichEdit во времени выполнения, не определяя родителя

Я должен использовать TRichEdit во времени выполнения для выполнения rtf для отправки текстовых сообщений преобразованию, как обсуждено здесь. Я успешно выполнился в выполнении этого, но я должен был установить фиктивную форму как родителя, если не я не могу заполнить TRichedit. Строки. (Ошибка: родитель отсутствует). Я вставляю свой funciton ниже, кто-либо может предложить способ постараться не определять родителя? Можно ли также прокомментировать это и сказать ли мне при нахождении более производительной идеи?

Примечание: Мне нужна строка, не TStrings, как произведено, это - то, почему она была разработана как это.

function RtfToText(const RTF: string;ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
  i: integer;
  CustomLineFeed: string;

begin
  if ReplaceLineFeedWithSpace then
    CustomLineFeed := ' '
    else
    CustomLineFeed := #13;
  try
    RTFConverter := TRichEdit.Create(nil);
    try
      MyStringStream := TStringStream.Create(RTF);
      RTFConverter.parent := Form4; // this is the part I don't like
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      for i := 0 to RTFConverter.Lines.Count - 1 do
      begin
        if i < RTFConverter.Lines.Count - 1 then
          Result := Result + RTFConverter.Lines[i] + CustomLineFeed
          else
          Result := Result + RTFConverter.Lines[i];
      end;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;

end;

ОБНОВЛЕНИЕ: После ответа я обновил функцию, и запишите это здесь для ссылки:

function RtfToText(const RTF: string;ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
begin
  RTFConverter := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    MyStringStream := TStringStream.Create(RTF);
    try
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      RTFConverter.Lines.StrictDelimiter := True;
      if ReplaceLineFeedWithSpace then
        RTFConverter.Lines.Delimiter := ' '
        else
        RTFConverter.Lines.Delimiter := #13;
      Result := RTFConverter.Lines.DelimitedText;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;
end;

18
задан Community 23 May 2017 в 12:02
поделиться

3 ответа

Элемент управления TRichEdit - это обертка вокруг элемента управления RichEdit в Windows. Элементы управления Windows - это... ну... Windows, и для работы им нужен Window Handle. Delphi нужно вызвать CreateWindow или CreateWindowEx для создания хэндла, и обеим процедурам для работы нужен действительный хэндл родительского окна. Delphi пытается использовать дескриптор родительского элемента управления (и это имеет смысл!). К счастью, можно использовать альтернативный конструктор (конструктор CreateParanted(HWND)), а добрые люди из Microsoft придумали HWND_MESSAGE, чтобы использовать его в качестве родителя для окон, которым на самом деле не нужно "окно" (только для сообщений).

Этот код работает как ожидалось:

procedure TForm2.Button2Click(Sender: TObject);
var R:TRichEdit;
    L:TStringList;
begin
  R := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    R.PlainText := False;
    R.Lines.LoadFromFile('C:\Temp\text.rtf');
    R.PlainText := True;

    Memo1.Lines.Text := R.Lines.Text;
  finally 
    R.Free;
  end;
end;
30
ответ дан 30 November 2019 в 06:59
поделиться

Я использую DrawRichText для рисования RTF без элемента управления RichEdit. (IIRC это называется Windowless Rich Edit Controls.) Возможно, вы можете использовать это и для конвертации - однако я никогда не пробовал.

4
ответ дан 30 November 2019 в 06:59
поделиться

Это часть способа работы VCL, и вы не сможете заставить его работать иначе без серьезных обходных путей. Но вам не нужно определять фиктивную форму в качестве родительской; просто используйте вашу текущую форму и установите visible: = false; в TRichEdit.

Если вы действительно хотите повысить производительность, вы можете отказаться от цикла, который вы используете для построения строки результата. Он должен много перераспределять и копировать память. Используйте свойство Text TrichEdit.Lines, чтобы получить CRLF между каждой строкой, и DelimitedText, чтобы получить что-то еще, например пробелы. Они используют внутренний буфер, который выделяется только один раз, что немного ускоряет конкатенацию, если вы работаете с большим количеством текста.

8
ответ дан 30 November 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: