-
Есть такой баг-демо: 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) Просто я бесконечно удивлен "долгожительством" этой баги. Может пора поправить, а ???
-
дык выложил бы исправление хотя бы для старой версии
-
Дык они отличаются как небо и земля. И не всегда в лучшую сторону :) А смысл очень простой: получивши 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;
Это пригодно только для демонстрации смысла сказанного, естественно
-
Ага смысл понял, но отличий действительно очень много.. хотя попробовать поковырять новую версию все же стоит..
-
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 …
-
Hallif вот Вы пальцем показали на ValidateRect, и соответствующий InvalidateRect для Sender.fParent Это категорически неправильно для случая, когда этот парент является owner-ом Неправильно, и все тут. Тут даже не очень важно, успел ли кто придумать визуализацию этого "неправильно". Не, ну можно сказать: " нет контр-примера - нет ошибки". Сказать-то можно, а ошибка - будет, еще через год... Ну нельзя же всю жизнь делать один и тот же код. В принципе, если приведенный Вами код из NEW_TRANSPARENT заменить на такой (кстати, первое условие там - это уже "давно проверенное" условие): if (not Sender.isForm)
and Sender.FParent.fDoubleBuffered
and (not Sender.fParentRequirePaint) then - то стартовой баги не видно. Зато становятся видны другие :) В общем, надо ставить "трассировщики", и со всем аккуратно разбираться. Правда мне казалось, что сделать это авторам сих TRANSPARENT-ов было бы на порядок проще :(
-
При OLD_TRANSPARENT глюка невидно почему не правильно то? оО И при NEW_TRANSPARENT после добавления (not Sender.isForm) тоже бага нет...
> - то стартовой баги не видно. Зато становятся видны другие > :)
какие другие?
-
> При OLD_TRANSPARENT глюка невидно почему не правильно то?
Это значит его будет видно кому-то через год. Оставлять неразорвавшиеся мины в чистом поле, даже если нашел обходной путь - это не правильно. Правильно - обезвреживать мины. "Мина", это когда по WM_PAINT в ClildForm он делается валидным, зато инвалидся MainForm. А делается именно так: коллега Hallif в это место пальцем ведь показал. Ну не нарисует MainForm ничего в ChildForm. Просто, чтобы это увидеть - нужны, наверное, более тонкие примеры... Которые рано или поздно появятся. И вот мне кажется, что правильней не искать эти примеры ради самих примеров, а мину напрочь обезвредить, а потом уже ждать примеров.
> какие другие?
а) минимизируем ChildForm, и видим артефакты на MainForm б) более того, усмотреть артефакты на MainForm можно и без фикса. Убираем прозрачность с Label1 (просто комментируем строку в стартовом примере) - типа все правильно работает и без фиксов. Дулю с маком, на самом деле. Передвигаем ChildForm, чтобы он перекрывал Label1, и опять минимизация. Вот вам и артефакты на Label1
-
Вот же ж блин :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); exit;
end;
-- то я перестаю наблюдать артефакты, которые я трудолюбиво описывал выше. Че к чему... Неужели получается, что теперь, для полного удовольствия -- осталось только придумать получение TR не тупо через BoundsRect, а через GetUpdateRect....
-
А у меня они остались =\ хотя с OLD_TRANSPARENT артефактов нет... КОЛ все же библиотека для создания компактного кода, поэтому кому надо то будет использовать OLD_TRANSPARENT.... и вот когда через Х лет найдет новый баг, тогда его и будут исправлять))
-
Ваша правда, коллега - остались. Это я глухо тупанул, Sorry :(
Да фигня все это. Чудес не бывает Исправлю, да и все... Один раз справился (с 1.69), и второй раз - тоже справлюсь. Кстати говоря, пытался "ее" насиловать аналогичными методами - ничего не вышло, все чистенько до противности. Похоже, что объем тестирования у нас был не хуже, чем здесь. Мягко говоря... Вот выберу свободное время только. Если уж Авторы отмалчиваются :(
-
Ну мнение авторов примерно отражено в 9 посте) Поэтому могу только пожелать свободного времени и удачи, либо забить до новых багов =)
-
Если в я чего решил, то выпью обязательно :D
Да, надо бы еще как-то придумать, как выделить из своих фиксов в 1.69-й те, которыми в 2.88 и не пахнет... Кроме SetCurIndex еще парочка-то -- точно найдется... Больше, наверное...
-
Я предлагаю выложить все фиксы =) возможно коллективно удастся "впихнуть" в новую версию
|