Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.14;
Скачать: CL | DM;

Вниз

Как избавится от мерцация формы при добавлении строк в Memo?   Найти похожие ветки 

 
Godness   (2006-03-25 22:36) [0]

Привет народ! Тут такая неприятная штука - мерцает TMemo при добавлении в нее строк и перемещении курсора на последнюю добавленную строку.

Основная форма добавляет строки при получении определенного сообщения.

function TLoginForm.KOLForm1Message(var Msg: tagMSG;
 var Rslt: Integer): Boolean;
begin
 Result := false;

 if Msg.message = MY_MESSAGE then
 begin
   Memo1.Add(string(Msg.lParam) + #13#10);
//    Memo1.Perform(EM_SCROLLCARET, 1, Memo1.Count - 1);    
   Memo1.Perform(EM_LINESCROLL, 1, Memo1.Count - 1);
   Result := true;
 end;
end;

Я пробывал ставить Memo1.Doublebuffer в true - тоже не помогает. При чем скорость добавления строк очень низкая 1-2 в секунду. Даже при этом видно, что полоска скроллинга сначала прыгает вверх, а потом вниз.


 
Godness   (2006-03-25 22:38) [1]

Может я не так использую EM_LINESCROLL. Всмысле, чего то может не хватает?


 
filer ©   (2006-03-28 20:49) [2]

Попробуй так:


...
Memo1.BeginUpdate;
Memo1.Add(string(Msg.lParam) + #13#10);
Memo1.Perform(EM_LINESCROLL, 1, Memo1.Count - 1);
Memo1.EndUpdate;
...


Проверил аналогичный код в своей программе, работает (наверно, оставлю свой вариант, хотя он, вроде, хуже). Но я ещё ни разу с сообщениями не работал (и KOL+MCK уже неделю как начал осваивать) - вдруг что не так.


 
filer ©   (2006-03-29 02:21) [3]

Такой глупости я от себя не ожидал (хотя мерцать должно стать меньше).

Ну раз уж начал лезть куда не следует, полезу ещё дальше.

Итак:

1. На мерцание забиваем и начинаем мерить скорость.

Тест (практического смысла в нём нет, просто тест):

1) 200 раз c помощью memo1.add добавляем по 1 строке с 1 символом.
2) за 1 раз добавляем 10000 строк по 50 символов.
3) повторяем шаг (1).

VCL справляется с первым шагом за 0.031 сек,со вторым за 0.265, с третьем за 0.062 (в этом запуске). KOL для этого потребовалось соответственно 0.015, 0.172 и 4.968. Несколько отличается.

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

4) раз VCL работает быстро, просто скопируем нужные куски оттуда.

Копируем код TMemoStrings.GetCount, TMemoStrings.Insert, TStrings.Add. После переименования получаем соответственно:


procedure Insert(Index: Integer; const S: string);
var
 SelStart, LineLen: Integer;
 Line: string;
begin
 if Index >= 0 then
 begin
   SelStart := SendMessage(form1.Memo1.Handle, EM_LINEINDEX, Index, 0);
   if SelStart >= 0 then Line := S + #13#10 else
   begin
     SelStart := SendMessage(form1.Memo1.Handle, EM_LINEINDEX, Index - 1, 0);
     if SelStart < 0 then Exit;
     LineLen := SendMessage(form1.Memo1.Handle, EM_LINELENGTH, SelStart, 0);
     if LineLen = 0 then Exit;
     Inc(SelStart, LineLen);
     Line := #13#10 + s;
   end;
   SendMessage(form1.Memo1.Handle, EM_SETSEL, SelStart, SelStart);
   SendMessage(form1.Memo1.Handle, EM_REPLACESEL, 0, Longint(PChar(Line)));
 end;
end;

function GetCount: Integer;
begin
 Result := 0;
 if form1.Memo1.HandleAllocated or (form1.Memo1.Text <> "") then
 begin
   Result := SendMessage(form1.Memo1.Handle, EM_GETLINECOUNT, 0, 0);
   if SendMessage(form1.Memo1.Handle, EM_LINELENGTH,
   SendMessage(form1.Memo1.Handle,
     EM_LINEINDEX, Result - 1, 0), 0) = 0 then Dec(Result);
 end;
end;

function print1(const S: string): Integer;
begin
 Result := GetCount;
 Insert(Result, S);
end;


Этот код достаточно быстро работает как на VCL, так и на KOL. Но на KOL появляется ограничение: больше 30000 символов в memo так не влезает. Почему? Не знаю; можно будет спросить об этом кого-нибудь.

Если согласиться терпеть это ограничение, то можно так:

procedure print(const s:string);
begin
 with form1.memo1^ do
  begin
   SelStart:=length(Text);
   {SelLength:=0;}
   ReplaceSelection(s+#13#10,false)
  end
end;


Тем не менее общий вывод таков: либо надо не слишком часто обращаться к memo.add, либо уж VCL использовать.

Надеюсь, что в дальнейшем буду сначала думать, а потом писать.


 
MTsv DN ©   (2006-03-29 11:45) [4]

Привет...

Единственный раз когда я встречал "тормоза" такого вида, это было при смене кода функции Convert2Mask (в версии 2.22) У меня очень догда прорисовывался TreeView с установленным Transparent"ом (я, кстати, до сих пор использую Convert2Mask v.2.21).

Если это та самая ситуация...то решение здесь: http://www.uus4u.com/download/other/kol_oldC2M.rar
Пояснения в архиве...

C Уважением MTsv DN


 
MTsv DN ©   (2006-03-29 11:47) [5]

> догда
...долго...



Страницы: 1 вся ветка

Текущий архив: 2007.01.14;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.051 c
1-1164122172
misha_gr
2006-11-21 18:16
2007.01.14
Как получить путь к папке %UserProfile%


3-1161663050
alucard
2006-10-24 08:10
2007.01.14
Как передать переменную в Rave отчёт?


15-1166510583
Fredy314
2006-12-19 09:43
2007.01.14
Интернет через ТВ кабель, как сделать.


2-1166926153
Drashka
2006-12-24 05:09
2007.01.14
Сравнение с типом данных Variant


2-1166698756
Gerda
2006-12-21 13:59
2007.01.14
Форма всегда на экране