Существует ли более быстрый компонент, чем TMemo, в CodeGear C ++ Builder? - PullRequest
3 голосов
/ 17 августа 2011

Я использую CodeGear C ++ Builder 2009 и у меня проблемы с компонентом TMemo. Это слишком медленно. Я использую его для отображения текста ASCII с последовательного порта COM. Мне нужно отобразить каждый символ, когда он идет от последовательного порта COM. Проблема в том, что если много текста из последовательного порта COM, старый текст на TMemo начинает мерцать, и чем больше текста на компоненте, тем хуже становится. Когда TMemo содержит 1000 строк текста, задержка обновления огромна!

Я установил для свойства doubleBuffered значение true, но это не помогает всем. Как сделать время обновления минимальным в таких приложениях, как SecureCRT? Новый текст добавляется плавно и не мерцает. Какой компонент может дать такой результат?

Ответы [ 2 ]

1 голос
/ 23 сентября 2011

Вместо того, чтобы отображать символы в реальном времени в TMemo по мере их поступления, попробуйте сначала сохранить их в буфере в памяти, а затем с коротким таймером периодически копировать буфер в TMemory и использовать Lines->BeginUpdate() и Lines->EndUpdate() методы при добавлении нового текста.Кроме того, 1000 строк это много, возможно, вам придется начать удалять старые строки, так как новые строки добавляются через некоторое время.Я обычно ограничиваю свои TMemo элементы управления несколькими сотнями строк за раз.

Обновление: попробуйте что-то вроде этого:

TMemoryStream *Buffer;

// serial port callback
void BytesReceived(void *Data, int Length)
{
    Buffer->Position = Buffer->Size;
    Buffer->WriteBuffer(Data, Length);
}

__fastcall TForm1::TForm1(TComponent *Owner)
    : TForm(Owner)
{
    Buffer = new TMemoryStream;
}

__fastcall TForm1::~TForm1()
{
    delete Buffer;
}

void __fastcall TForm1::TimerElapsed(TObject *Sender)
{
    if (Buffer->Size > 0)
    {
        Memo1->Lines->BeginUpdate();
        Memo1->SelStart = Memo1->GetTextLen();
        Memo1->SelLength = 0;
        Memo1->SelText = AnsiString((char*)Buffer->Memory, Buffer->Size);
        Memo1->SelStart = Memo1->GetTextLen();
        Memo1->Perform(EM_SCROLLCARET, 0, 0);
        Memo1->Lines->EndUpdate();
        Buffer->Clear();
    }
}
0 голосов
/ 31 мая 2013

как для оконных устройств. , Лучший способ - использовать событие потока вместо события таймера. , поместить последовательное событие ожидания в thread->execute(), (это цикл do while,.)

событие последовательного ожидания ничего не изменит, пока что-то не получит, .. вскоре он получил в *buffer, проверить длину буфера / строки,. .

затем укажите в памятке как

memo->text=buffer;
or 
memo->lines-add(buffer);
...