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

Вниз

Очень Древний Баг с прозрачностью (DoubleBuffered)   Найти похожие ветки 

 
Galkov   (2009-06-10 22:14) [0]

Есть такой баг-демо:
Program test;
uses  windows,kol;

var MainForm,ChildForm,Label1,Label2:PControl;

begin
 Applet    := NewApplet("Bug-Demo");
//главная форма
 MainForm  := NewForm (Applet, "Main Form").SetPosition(120,120).SetSize(400,200);
 Label1    := NewLabel(MainForm, "TEST-1").SetPosition( 20, 20);
 Label1.Transparent := true;
//дочерняя форма
 ChildForm := NewForm (MainForm, "Child Form").SetPosition(220,220).SetSize(400,200);
 Label2    := NewLabel(ChildForm,"TEST-2").SetPosition( 20, 20);
 Label2.Transparent := true;
//поехали...
 Run(Applet);
end.


По неким причинам, связанным с совместимостью, у меня в работе "правленная" 1.69
И там это исправлено. Т.е., мне известна причина баги, и способы ее устранения (чего уже не скажу про версию 2.88)
Просто я бесконечно удивлен "долгожительством" этой баги.
Может пора поправить, а ???


 
D[u]fa   (2009-06-11 10:35) [1]

дык выложил бы исправление хотя бы для старой версии


 
Galkov   (2009-06-11 11:23) [2]

Дык они отличаются как небо и земля. И не всегда в лучшую сторону :)

А смысл очень простой: получивши ivalidate в нижнем контролле, мы всегда "передаем" его на верх. Тому, кто и будет рисовать на самом деле.
Так вот: не надо передавать енто паренту тупо, на ФОРМЕ следует таки остановиться.
Вот и вся премудрость...

В старых версиях этим делом занимался TControl.DblBufTopParent, и в нем фикс элементарен:

function TControl.DblBufTopParent: PControl;
var Ctl: PControl;
begin
 Result := nil;
 Ctl := @ Self;
 while Ctl <> nil do
 begin
   if Ctl.fDoubleBuffered then
     Result := Ctl;
   if Ctl.isForm then exit; // <-- да вот он
   Ctl := Ctl.fParent;
 end;
end;


Это пригодно только для демонстрации смысла сказанного, естественно


 
D[u]fa   (2009-06-11 15:07) [3]

Ага смысл понял, но отличий действительно очень много.. хотя попробовать поковырять новую версию все же стоит..


 
Hallif ©   (2009-06-12 19:20) [4]

Galkov, попробуйте с директивой OLD_TRANSPARENT
Начиная с версии 2.24 введена функция WndProcTransparent, которая на данный момент представлена в двух вариантах: базовая и модифицированная фаст-версия (автор Александр Карпинский). В фаст-версии  часть условий была вынесена из цикла обработки сообщений.
В частности, эпизод WM_PAINT:  

ValidateRect(Sender.fHandle, nil);
   if (Sender.fTransparent) and (not Sender.fParentRequirePaint) then begin
                    InvalidateRect(Sender.fParent.Handle, nil, FALSE);
                    Result := TRUE;

теперь находится в несколько измененном виде под условием

if (Sender.fTransparent or Sender.fDoubleBuffered)
 and (Sender.FParent <> nil)
 and Sender.FParent.fDoubleBuffered
 and (not Sender.fParentRequirePaint)  then…

Предположительно для дочернего контролла существует альтернативный вызов при
fTransparent =0, fDoubleBuffered=1
Решением в данном случае, будет скорее всего замена части условия на
if (Sender.fTransparent or (not Sender.fDoubleBuffered)…
или вообще на   if Sender.fTransparent …


 
Galkov   (2009-06-12 22:59) [5]

Hallif вот Вы пальцем показали на ValidateRect, и соответствующий InvalidateRect для Sender.fParent
Это категорически неправильно для случая, когда этот парент является owner-ом
Неправильно, и все тут.
Тут даже не очень важно, успел ли кто придумать визуализацию этого "неправильно".
Не, ну можно сказать: "нет контр-примера - нет ошибки".
Сказать-то можно, а ошибка - будет, еще через год... Ну нельзя же всю жизнь делать один и тот же код.

В принципе, если приведенный Вами код из NEW_TRANSPARENT заменить на такой (кстати, первое условие там - это уже "давно проверенное" условие):

 if (not Sender.isForm)
 and Sender.FParent.fDoubleBuffered
 and (not Sender.fParentRequirePaint) then


- то стартовой баги не видно. Зато становятся видны другие :)

В общем, надо ставить "трассировщики", и со всем аккуратно разбираться.
Правда мне казалось, что сделать это авторам сих TRANSPARENT-ов было бы на порядок проще :(


 
D[u]fa   (2009-06-14 11:00) [6]

При OLD_TRANSPARENT глюка невидно почему не правильно то? оО
И при NEW_TRANSPARENT после добавления (not Sender.isForm) тоже бага нет...


> - то стартовой баги не видно. Зато становятся видны другие
> :)


какие другие?


 
Galkov   (2009-06-14 20:43) [7]


> При OLD_TRANSPARENT глюка невидно почему не правильно то?

Это значит его будет видно кому-то через год.
Оставлять неразорвавшиеся мины в чистом поле, даже если нашел обходной путь - это не правильно. Правильно - обезвреживать мины.
"Мина", это когда по WM_PAINT в ClildForm он делается валидным, зато инвалидся MainForm.
А делается именно так: коллега Hallif в это место пальцем ведь показал.
Ну не нарисует MainForm ничего в ChildForm. Просто, чтобы это увидеть - нужны, наверное, более тонкие примеры... Которые рано или поздно появятся.
И вот мне кажется, что правильней не искать эти примеры ради самих примеров, а мину напрочь обезвредить, а потом уже ждать примеров.


> какие другие?

а) минимизируем ChildForm, и видим артефакты на MainForm
б) более того, усмотреть артефакты на MainForm можно и без фикса. Убираем прозрачность с Label1 (просто комментируем строку в стартовом примере) - типа все правильно работает и без фиксов. Дулю с маком, на самом деле.
Передвигаем ChildForm, чтобы он перекрывал Label1, и опять минимизация.
Вот вам и артефакты на Label1


 
Galkov   (2009-06-14 20:58) [8]

Вот же ж блин :shock:
Если вышеприведенный мной "якобы фикс" делать в таком виде (разница - жирная):

 if (Sender.fParent<>nil) and (not Sender.isForm)
 and Sender.FParent.fDoubleBuffered
 and (not Sender.fParentRequirePaint) then
 begin
   TR := Sender.BoundsRect;
   InvalidateRect(Sender.fParent.fHandle, @TR, true);
   ValidateRect(Sender.fHandle, nil);  //???--brandys???+
   exit;
 end;


-- то я перестаю наблюдать артефакты, которые я трудолюбиво описывал выше.
Че к чему...

Неужели получается, что теперь, для полного удовольствия -- осталось только придумать получение TR не тупо через BoundsRect, а через GetUpdateRect....


 
D[u]fa   (2009-06-14 22:05) [9]

А у меня они остались =\
хотя с OLD_TRANSPARENT артефактов нет... КОЛ все же библиотека для создания компактного кода, поэтому кому надо то будет использовать OLD_TRANSPARENT.... и вот когда через Х лет найдет новый баг, тогда его и будут исправлять))


 
Galkov   (2009-06-15 08:56) [10]

Ваша правда, коллега - остались. Это я глухо тупанул, Sorry :(

Да фигня все это. Чудес не бывает
Исправлю, да и все... Один раз справился (с 1.69), и второй раз - тоже справлюсь.
Кстати говоря, пытался "ее" насиловать аналогичными методами - ничего не вышло, все чистенько до противности. Похоже, что объем тестирования у нас был не хуже, чем здесь. Мягко говоря...
Вот выберу свободное время только.
Если уж Авторы отмалчиваются :(


 
D[u]fa   (2009-06-15 10:05) [11]

Ну мнение авторов примерно отражено в 9 посте)
Поэтому могу только пожелать свободного времени и удачи, либо забить до новых багов =)


 
Galkov   (2009-06-15 17:20) [12]

Если в я чего решил, то выпью обязательно :D

Да, надо бы еще как-то придумать, как выделить из своих фиксов в 1.69-й те, которыми в 2.88 и не пахнет...
Кроме SetCurIndex еще парочка-то -- точно найдется... Больше, наверное...


 
D[u]fa   (2009-06-16 09:59) [13]

Я предлагаю выложить все фиксы =) возможно коллективно удастся "впихнуть" в новую версию



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

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

Наверх




Память: 0.51 MB
Время: 2.644 c
2-1337284179
Vasia
2012-05-17 23:49
2013.03.22
Как прописать путь к файлу что бы он отображался...


15-1346515594
Artem
2012-09-01 20:06
2013.03.22
Как передать файл на 2 Мб на древний DOS ноутбук?


2-1334607403
Непомнящий
2012-04-17 00:16
2013.03.22
Кончается память


2-1345111451
Дмитрий Белькевич
2012-08-16 14:04
2013.03.22
Найти вернее окно (форму) среди нескольких одинаковых


6-1250966588
Pirog
2009-08-22 22:43
2013.03.22
Page Rank