Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26170
Рейтинг: 2127
#61: 2008-04-09 00:39:56 ЛС | профиль | цитата
Вот еще сомнительная тема


   WM_SETTEXT:
begin
if not Self_.fIsStaticControl or (Self_.DblBufTopParent = nil) then Exit;
ShowWindow( Self_.fHandle, SW_HIDE );
Rslt := DefWindowProc( Self_.fHandle, WM_SETTEXT, Msg.wParam, Msg.lParam );
ShowWindow( Self_.fHandle, SW_SHOWNA );
UpdateWindow( Self_.fHandle ); // necessary!!!
Result := True;
end;

Работает при fIsStaticControl = true (To prevent flickering it in DoubleBuffered mode). Включен по-умолчанию в Label. Никакой разницы не заметил, ни с ним, ни без него.

------------ Дoбавленo:


Вот смотри, что я сделал


function WndProcBufferedDraw( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
begin
Result := False;
if Self_.fCannotDoubleBuf or (Self_.DblBufTopParent = nil) then Exit;
case Msg.message of
WM_PAINT:
begin
if Self_.DblBufTopParent <> Self_ then begin
if (not Self_.DblBufTopParent.fDblBufPainting) or (Self_.DblBufTopParent.fPaintDC = 0) then begin
ValidateRect( Self_.fHandle, nil );
if not Self_.DblBufTopParent.fDblBufPainting then Self_.DblBufTopParent.Invalidate;
Rslt := 0;
Result := True;
end;
Exit;
end;
if Msg.wParam = 0 then DoDrawDblBuffered( Self_ );
end;
WM_HSCROLL, WM_VSCROLL, WM_WINDOWPOSCHANGED: Self_.Invalidate;
WM_COMMAND: case HiWord( Msg.wParam ) of LBN_SELCHANGE: Self_.Invalidate; end;
end;
end;
У меня, в твоей схеме, в два раза уменьшилось количество обращений и все примеры продолжают работать
карма: 22

0
Ответов: 9906
Рейтинг: 351
#62: 2008-04-09 01:12:39 ЛС | профиль | цитата
Фигню ты сделал
Рассчитывать на то, что Invalidate для Top-а сделает TControl.Invalidate - НЕЛЬЗЯ.
Потому-что существуют и другие средства инвалидности. И уж сама винда точно этот метод вызывать не будет
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#63: 2008-04-09 01:34:12 ЛС | профиль | цитата
Galkov писал(а):
Фигню ты сделал
Ну, я только попробовал, проверил (и в основном не Invalidate, а влияние WM_ERASEBKGND, WM_NCPAINT и WM_SETTEXT на визуальное отображение). Хотя вот с этим

Galkov писал(а):
Потому-что существуют и другие средства инвалидности. И уж сама винда точно этот метод вызывать не будет


я согласен. Действительно

Galkov писал(а):
Рассчитывать на то, что Invalidate для Top-а сделает TControl.Invalidate - НЕЛЬЗЯ




------------ Дoбавленo:


Вернул Self_.DblBufTopParent.Invalidate сразу подскачило количество обращений(код наверху тоже поправил, вдруг кто еще захочет попробовать). Тут что получается, или нам искать другой путь избавления от избыточности, или так все и оставить.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#64: 2008-04-09 01:48:34 ЛС | профиль | цитата
Соображение:
Для контрола на котором произошла инвалидность, WndProcBufferedDraw должно вызываться дважды: первый раз, понятно - это делает винда реагируя на Invalidate, второй раз это делают DoDrawDblBuffered и DoDrawChildrenDblBuffered через SendMessage

Это будет неправильно, если ДВА раза вместо одного это (WM_ERASEBKGND, WM_NCPAINT) отправится в default-обработку
Просто неправильно, и все.
Даже проверять не буду - вышестоящее соображение обладает более высоким приоритетом, чем функционирование каккого-то количества примеров.
Следствие простого профессионального принципа: из того что это работает сейчас вовсе НЕ СЛЕДУЕТ, что это будет работать всегда

Наша задача сегодня, чтобы это работало всегда. Это более сложно, чем заставить дышать какой-то конкретный код.
В принципе, это две разные профессии.
Аналог в электронике: цель у наладчика, рационализатора, радиолюбителя - оживить конкретное изделие
Вот они и пользуются методом тыка.
Цель у разработчика - чтобы это работало всегда (когда начнется выпуск, он уволится уже, и т.п.)

Вот поэтому у них и существует лозунг: встретил рационализатора - убей его (в командировку на объект-то им ездить приходится)
Это все не я придумал, естественно - на познание с нуля таких истин не всякой жизни хватит...
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#65: 2008-04-09 01:49:05 ЛС | профиль | цитата
Тут еще прикол заметил -- если захватить любой контрол, то при наложении на другой, он уйдет под него, но если отпустить мышь и захватить снова, то он переместиться наверх.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#66: 2008-04-09 01:56:16 ЛС | профиль | цитата
nesco писал(а):
Тут что получается, или нам искать другой путь избавления от избыточности, или так все и оставить

ИСКАТЬ - такие вопросы даже задавать стыдно должно быть
Galkov писал(а):
Придется по-взрослому писать debug-кусочки с сохранением в файл и с пристрастием изучать это безобразие

------------ Дoбавленo:

nesco писал(а):
то при наложении на другой, он уйдет под него, но если отпустить мышь и захватить снова, то он переместиться наверх.

Ничего не уходит - какой был до этого Z, такой и остается.
А вот при отпускании - да, лезет наверх

Но это другой разговор совсем. Так работает виндячий MOVE для формы (любой)
Элемент просто эмулирует именно эту команду системного меню - посмотри коды....
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#67: 2008-04-09 02:00:46 ЛС | профиль | цитата
Насчет WM_NCPAINT, я ничего не скажу, ну вот WM_ERASEBKGND выполняется еще и в DoDrawDblBuffered, и в DoDrawChildrenDblBuffered, а что насчет WM_SETTEXT
Или все пока оставить в последнем рабочем варианте со всеми обработчиками, до поиска наилучшего решения
------------ Дoбавленo:

Galkov писал(а):
Так работает виндячий MOVE для формы (любой)
Элемент просто эмулирует именно эту команду системного меню - посмотри коды....

Спасибо, что подсказал...
карма: 22

0
Ответов: 9906
Рейтинг: 351
#68: 2008-04-10 13:48:22 ЛС | профиль | цитата
Значит так...

1) чтобы убрать "лишние бипы" надо:

  • выкинуть Global_Invalidate из KOL вообще напрочь - только и делает, что добавляет лишние рисования
  • в WndProcPaint заменить WM_PRINT на WM_PRINTCLIENT, а то есть реакция не в тему на SendMessage(W,WM_PRINT,DC,PRF_NONCLIENT) из DoDrawChildrenDblBuffered

    2) наблюдения за последовательностью происходящего с помощью LogFileOutput показывают:

  • ошибся я, и двойное onPaint, после предложенного тобой фикса, возникает не у инвалидного контролла, а у TOP-а. Но это тоже не есть хорошо...
  • получается так, что (при прозрачности) за каким-то лядом вызывается рисование невидимого контролла (по крайней мере, первый раз), и никак ему валидность сделать не удается (без вызова DefWindowProc). И сидит в очереди этот WM_PAINT, точно его заклинило, и все время непрерывно обрабатывается...
  • поэтому такое компромиссное предложение
    
    #pas
    .....
    if Self_DblBufTopParent.fDblBufPainting then Exit;
    DoDrawDblBuffered( Self_ );
    if not IsWindowVisible( Self_.fHandle ) then exit;
    Rslt := 0;
    Result := True;
    end;
    на вид глупо, но работает...
  • чтобы уменьшить объем рисования, хорошо бы делать ValidateRect для всех уже отрисованных контроллов в DoDrawChildrenDblBuffered Скажем, включаем видимость (да хоть бы и той же формы), а там ВСЕ инвалидное...
    И начинается: отрисовали один раз, второй - ровно то же самое, третий - ровно то же самое....
    что к чему....
    ------------ Дoбавленo:

    Про WM_SETTEXT...
    В этой схеме, без обработчика (как ты предлагаешь) - флики ЕСТЬ
    Add(Timer,13184380,112,35)
    {
    Interval=10
    link(onTimer,15760076:doData,[])
    }
    Add(Label,4699369,315,35)
    {
    Left=35
    Top=70
    Width=200
    Height=30
    Color=12632256
    Font=[Arial Black,18,1,255,204]
    Caption="TEST1"
    AutoSize=1
    Alignment=2
    Point(onMouseDown)
    Point(Handle)
    }
    Add(DoData,15760076,168,35)
    {
    Data=String(TEST-TEST)
    link(onEventData,10987532:doEvent1,[])
    }
    Add(Label,7314866,315,91)
    {
    Left=35
    Top=30
    Width=200
    Height=30
    Color=12632256
    Font=[Arial Black,18,1,255,204]
    Transparent=0
    Caption="TEST"
    AutoSize=1
    Alignment=2
    Point(onMouseDown)
    Point(Handle)
    }
    Add(Hub,10987532,231,35)
    {
    link(onEvent1,4699369:doText,[])
    link(onEvent2,7314866:doText,[(289,48)(289,97)])
    }
  • карма: 9

    0
    Разработчик
    Ответов: 26170
    Рейтинг: 2127
    #69: 2008-04-10 14:01:43 ЛС | профиль | цитата
    Galkov писал(а):
    В этой схеме, без обработчика (как ты предлагаешь) - флики ЕСТЬ

    Да, есть. Еле заметный, но есть.

    ------------ Дoбавленo:

    Galkov писал(а):
    хорошо бы делать ValidateRect для всех уже отрисованных контроллов в DoDrawChildrenDblBuffered

    Это вот так

    
             SendMessage( W, WM_ERASEBKGND, DC, 0 );
    SendMessage( W, WM_PAINT, DC, 0 );
    DoDrawChildrenDblBuffered( DC, W, CR, GetWindow( W, GW_CHILD ) );
    RestoreDC( DC, Save );
    ValidateRect( W, nil );
    end;
    W := GetWindow( W, GW_HWNDPREV ); // get handle previous window same level
    end;
    end;

    карма: 22

    0
    Ответов: 9906
    Рейтинг: 351
    #70: 2008-04-10 14:03:28 ЛС | профиль | цитата
    Ну может и так...
    Хотя я выносил это из под IF-а
    карма: 9

    0
    Разработчик
    Ответов: 26170
    Рейтинг: 2127
    #71: 2008-04-10 14:12:13 ЛС | профиль | цитата
    nesco писал(а):
    Хотя я выносил это из под IF-а

    Но тогда получается, что у нас невидимое окно всегда валидное
    карма: 22

    0
    Ответов: 9906
    Рейтинг: 351
    #72: 2008-04-10 14:26:03 ЛС | профиль | цитата
    Это уже рассуждения двух сумашедших: а если невидимое окно всегда инвалидное, то мы все ваемя будем получать и обрабатывать WM_PAINT на него
    А реализацию, при этом, сделал третий сумашедший - Билл
    карма: 9

    0
    Разработчик
    Ответов: 26170
    Рейтинг: 2127
    #73: 2008-04-10 14:34:48 ЛС | профиль | цитата
    Galkov писал(а):
    то мы все ваемя будем получать и обрабатывать WM_PAINT на него

    И правда, на кой черт нам лишний пустой вызов WM_PAINT
    ------------ Дoбавленo:

    Galkov, я там новый апдэйт на KOL кинул, посмотри все ли правильно. Сделал все, что рекомендовано.
    карма: 22

    0
    Ответов: 9906
    Рейтинг: 351
    #74: 2008-04-10 14:56:47 ЛС | профиль | цитата
    Ну я все равно его подновлю, наверное.
    Не торопясь шибко...


    Вот что...
    Скинь мне на мыло ОРИГИНАЛ kol_for_fpc, чтобы я не напрягался....
    Если уж патчить его, тогда надо:
  • прошерсть все дефайны на F_P - там это в половине случаев идет как НЕ Дельфячее регистровое соглашение
  • прошерстить все RET-ы в оставшихся asm-кусочках
  • повылавливать собак перед Self-ом - не исключены варианты
  • исправить NewThread - он ведь и сам его иногда использует
  • перенести тогда уж ВСЕ фиксы с дельфячего kol-а
  • может и еще чего - сразу и не вспомню...
    Пока в отпуске - потрачу пару дней....
  • карма: 9

    0
    Разработчик
    Ответов: 26170
    Рейтинг: 2127
    #75: 2008-04-10 15:31:24 ЛС | профиль | цитата
    Galkov писал(а):
    Скинь мне на мыло ОРИГИНАЛ kol_for_fpc

    Отправил.
    карма: 22

    0
    Сообщение
    ...
    Прикрепленные файлы
    (файлы не залиты)