Форум: "KOL";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизОчень Древний Баг с прозрачностью (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 вся ветка
Форум: "KOL";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.077 c