Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как вставить текст в конец Memo


Автор: Hacker 21.3.2006, 15:12
Помогите. Ситуация такая: прога читает данные с COM-порта и заносит их в memo по мере поступления.
Если применять метод memo.text:=memo.text+s; // то текст мемки будет весь копироваться.
Во-первых это приведёт к миганию, а во вторых если наберётся МНОГО данных, прога не будет успевать копировать текст и принимать данные с порта.

Вопрос: как можно добавлять текст в конец memo, НО чтобы он добавлялся НЕ как строка (memo.lines.append()), а просто дописывался без перерисовки всего компонента и без копирования всего содержимого мемки в неё же.

Автор: bems 21.3.2006, 15:18
Промежуточный вариант: memo.lines[memo.lines.count-1]:=memo.lines[memo.lines.count-1]+s

Автор: Alexeis 21.3.2006, 15:21
Hacker, с одной строкой будет тотже эффект
может имеет смысл накапливать текст скажем по 1024 байта, а потом добавлять к какому-нибудь буферу.
Можно использвать TMemorystreem
Если не нужно перерисовывать так зачем вообще его отображать прямо сразу smile

Автор: Hacker 21.3.2006, 15:53
2 alexeis1 Я имел ввиду, что не нужно перерисовывать весь текст, просто добавлять и всё (например пишешь в delphi прогу, она же не перерисовывает весь текст проги при вводе каждого символа).

2 bems Спасибо, как я сам не додумался.

Может у кого есть ещё идеи, желательно чтобы курсор оставался на месте и не трогался программой (чтобы пользователь мог просматривать, прокручивать и даже редактировать текст во время приёма данных).

P.S: Блин, даже не ожидал получить ответы так быстро, бывает задашь вопрос (на других форумах) - неделя, две... ответов нету smile

Автор: Snowy 21.3.2006, 16:05
Цитата(Hacker @ 21.3.2006, 15:53 Найти цитируемый пост)
желательно чтобы курсор оставался на месте и не трогался программой
Перед вставкой запоминай SelStart, после вставки восстанавливай.

Цитата(Hacker @ 21.3.2006, 15:53 Найти цитируемый пост)
Блин, даже не ожидал получить ответы так быстро
У нас на простые вопросы только ночью задержка бывает до 3-х часов. А днем минут 15 максимум.

Автор: bems 21.3.2006, 16:06
Цитата(Hacker @ 21.3.2006, 15:53 Найти цитируемый пост)
бывает задашь вопрос (на других форумах) - неделя, две... ответов нету

эт смотря какой вопрос smile

Автор: Alexeis 21.3.2006, 16:07
Hacker, я не понял, текст многострочный или просто одна длинная строка.
Если многострочный, то может накапливать текст до символа конец строки, а затем добавлять эту строку memo1.add(s);

Автор: Hacker 21.3.2006, 16:33
Цитата

Текст многострочный или просто одна длинная строка?


Текст ОЧЕНЬ_МНОГОстрочный.

Цитата

Если многострочный, то может накапливать текст до символа конец строки, а затем добавлять эту строку memo1.add(s);


Текст принимается из буфера порта таймером каждые 50 мс, следовательно он идёт пакетами по n байт (max-128), значит придётся каждые 50 мс "проезжать" по строке до ближайшего Enter'а(если он будет), а как быть с последней строкой, если после неё не будет #13, то она не добавится в memo, ведь прога не знает, когда считать чтение законченным - это определяет пользователь, а вообще этот способ я попробую.

Вот код, которым у меня сейчас считываются данные:

Код

procedure TfrmInputTah.TimerReadTimer(Sender: TObject);
begin
  ReadFile(hPort,ReadBuff,128,NumbBytesRead,nil);
  BytesRead:=LeftStr(ReadBuff,NumbBytesRead);
  if BytesRead<>'' then
    memo.Text:=memo.Text+BytesRead;
end;


Вместо BytesRead для проверки можно подставить например '1234567';

Щас буду пробовать. smile

Автор: Romikgy 21.3.2006, 16:46
А если двойную буферизацию, и делать как раньше

Автор: Hacker 21.3.2006, 17:16
Вроде решил. Подкорректируйте, если найдёте скрытые ошибки. Испытал-пока работает.

Код

procedure TfrmInputTah.TimerReadTimer(Sender: TObject);
var rs:integer;
begin
  ReadFile(hPort,ReadBuff,128,NumbBytesRead,nil);
  BytesRead:=LeftStr(ReadBuff,NumbBytesRead);
  if BytesRead<>'' then begin
    for rs:=1 to length(BytesRead) do begin
      if BytesRead[rs]<>chr(10) then
        BytesBuffer:=BytesBuffer+BytesRead[rs];
    end;
    if BytesBuffer='' then exit;
    if BytesBuffer[1]=chr(13) then BytesBuffer:=RightBStr(BytesBuffer,length(BytesBuffer)-1);
    for rs:=1 to length(BytesBuffer) do begin
      if BytesBuffer[rs]=chr(13) then begin
        memo.Lines.Add(leftstr(BytesBuffer,rs-1));
        BytesBuffer:=RightStr(BytesBuffer,length(BytesBuffer)-rs);
        break;
      end;
    end;
  end;
end;


Всем спасибо за ответы!

Автор: Poseidon 21.3.2006, 20:07
Цитата(Snowy @ 21.3.2006, 15:05 Найти цитируемый пост)
У нас на простые вопросы только ночью задержка бывает до 3-х часов. А днем минут 15 максимум.
Ага, а когда Snowy на форуме, то ты еще обновить страницу не успеешь, а уже ответ получишь smile

Цитата(Hacker @ 21.3.2006, 14:53 Найти цитируемый пост)
например пишешь в delphi прогу, она же не перерисовывает весь текст проги при вводе каждого символа
Так ведь и Мемо не перерисовывает при вводе символов. А вот если програма сама выводит в Мемо...

Автор: Демо 21.3.2006, 20:12
Hacker,

Простой пример:

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  Memo1.Lines.BeginUpdate;
  for i := 0 to 1000 do
  begin
    Memo1.Lines.Add(IntToStr(i));
  end;
  Memo1.Lines.EndUpdate;
end;


Автор: Hacker 21.3.2006, 20:56
Метод Add добавляет СТРОКУ в конец и перекидывает каретку, а мне нужно, чтобы просто добавлялись символы. Вот например, есть у меня в memo текст:
Код

Delphi


если я напишу memo.lines.add(' rulit!!!') или memo.lines.append(' rulit!!!'), то у меня получится:
Код

Delphi
 rulit!!!


А мне нужно, чтобы получилось:
Код

Delphi rulit!!!


И чтоб ещё при этом курсор остался на месте и текст в мемке не мигал как ёлка новогодняя. smile

Ещё пример: мы можем писАть в файл функцией WriteLn, тогда она к нашей строке прибавит '$A$D', а можем использовать просто Write, и тогда ничего не добавится.

Так вот memo.lines.add() добавляет сзади к строке '$A$D', которые мне совсем не нужны.

Автор: Демо 21.3.2006, 21:04
Цитата(Hacker @ 21.3.2006, 20:56 Найти цитируемый пост)
Метод Add добавляет СТРОКУ в конец и перекидывает каретку, а мне нужно, чтобы просто добавлялись символы.


Тогда так:

Код

procedure TForm1.Button2Click(Sender: TObject);
var
  n: integer;
begin
  Memo1.DoubleBuffered := True;
  n := Memo1.SelStart;
  Memo1.Lines.BeginUpdate;
  Memo1.Lines[Memo1.Lines.Count-1] := Memo1.Lines[Memo1.Lines.Count-1]+'qweqwe';
  Memo1.Lines.EndUpdate;
  Memo1.SetFocus;
  Memo1.SelStart := n;
end;


Автор: Hacker 21.3.2006, 21:54
Демо. Работает, но с глюками. Иногда две строки подряд в одну запихивает. Если писать memo.text:=memo.text+s; тогда такого не бывает.

Вот, что получается с твоим примером:
Код

*110001+0000000000000001 21.324+0000000033704490 22.324+0000000009017500 31...0+0000000000015906 81...0+0000000000993805 82...0+0000000002014650 83...0+0000000000646987 87...0+0000000000001630 *110002+0000000000000002 21.324+0000000003828180 22.324+0000000009029250 31...0+0000000000026242 81...0+0000000001016325 82...0+0000000002020545 83...0+0000000000646846 87...0+0000000000001630 
*110003+0000000000000003 21.324+0000000005605320 22.324+0000000009039110 31...0+0000000000050061 81...0+0000000001041545 82...0+0000000002027925 83...0+0000000000646500 87...0+0000000000001630 
*110004+0000000000000004 21.324+0000000007510010 22.324+0000000009045410 31...0+0000000000084162 81...0+0000000001081350 82...0+0000000002021544 83...0+0000000000645952 87...0+0000000000001630 
*110005+0000000000000005 21.324+0000000009909580 22.324+0000000009037290 31...0+0000000000088748 81...0+0000000001087610 82...0+0000000001985864 83...0+0000000000646103 87...0+0000000000001630 
*110006+0000000000000006 21.324+0000000011408320 22.324+0000000009034570 31...0+0000000000104615 81...0+0000000001095460 82...0+0000000001957214 83...0+0000000000646007 87...0+0000000000001630 
*110007+0000000000000007 21.324+0000000012549400 22.324+0000000009039390 31...0+0000000000128754 81...0+0000000001104384 82...0+0000000001924638 83...0+0000000000645586 87...0+0000000000001630 
*110008+0000000000000008 21.324+0000000013243030 22.324+0000000009044470 31...0+0000000000151439 81...0+0000000001111254 82...0+0000000001897275 83...0+0000000000645099 87...0+0000000000001630 



Как видишь, в первой строке запихана и вторая и появилась одна пустая строка.

Такое возможно если в буфере окажется только $A или $A$D или $D
Добавлено @ 22:02
Цитата

Такое возможно если в буфере окажется только $A или $A$D или $D


Нет не правду сказал.
Такое возможно если в конце буфера окажется $A или $A$D или $D

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)