Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.09 c
15-1329244892
Lamer@fools.ua
2012-02-14 22:41
2013.03.22
Странное поведение CHOICE (batch file)


15-1341390679
alexdn
2012-07-04 12:31
2013.03.22
Индексация припаркованного домена


2-1347120747
123456789igor
2012-09-08 20:12
2013.03.22
excel в delphi цикл по строкам


2-1329256529
Deltas
2012-02-15 01:55
2013.03.22
Что за... сообщение в Delphi XE2.


2-1335103508
Gedimen
2012-04-22 18:05
2013.03.22
Коряво работает свой компоннет на основе TEdit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский