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

Вниз

Изменение порядка прорисовки   Найти похожие ветки 

 
homm ©   (2005-11-24 22:04) [0]

Есть панель (родитель) и компоненты (дети). При необходимости прорисовки сообщения идут в следуещем порядке:

WM_ERASEBKGND родителя
WM_ERASEBKGND всех детей
WM_PAINT родителя
WM_PAINT всех детей

Мне необходимо чтобы сообщения шли в следующей последовательности:

WM_ERASEBKGND (не имеет значения чей)
WM_PAINT всех детей
WM_PAINT родителя

Другими словами при наличии не прорисованых областей у родителя и детей прооритет в прорисовке отдается имено родителю. Нужно чтобы отрисовывались сначала дети. Подозреваю что это дело осуществляется с помощью стилей.
Предлагаю посмотреть проект на KOL"е, может он внесет ясность в постановку задачи.
http://www.homm86.narod.ru/files/messages.zip


 
Германн ©   (2005-11-25 02:15) [1]


> Предлагаю посмотреть проект на KOL"е, может он внесет ясность
> в постановку задачи.


Дык есть же соответствующая конференция по KOL. Зачем же сюда?


 
homm ©   (2005-11-25 05:36) [2]

Это просто тестовый проект, который поможет понять задачу и возможно ее решить. Добиватся результата нужно все равно через WinApi. Средствами KOL этого не сделать.


 
clickmaker ©   (2005-11-25 09:56) [3]

попробуй со стилем WS_EX_TRANSPARENT поиграть. Но боюсь, придется наследников писать и перекрывать CreateParams


 
Суслик ©   (2005-11-25 13:14) [4]

можно еще с регионами поиграть
см. SetWindowRgn.


 
homm ©   (2005-11-25 18:12) [5]

Ну и при чем здесь регионы?
Если бы описаное в [0] было бы не так, то WS_EX_TRANSPARENT давало бы наверное такой эфект.
Почему чем конкретнее и правильнее задан вопрос, тем меньше желающих дать правильный ответ?


 
Суслик ©   (2005-11-25 18:37) [6]

зачем же так возмущаться?
сделай дырку в дочернем компоненте, через него будет виден родитель.
вот, собственно, "причем" регионы.


 
homm ©   (2005-11-25 19:43) [7]

Отлично! У меня теперь дырка есть! Ты [0] читал? Где там про то, что нужно что-то увидеть? Все что нужно и так видно. Только нужно чтобы было в другой последовательности видно  - сначала дети, потом родители.


 
Суслик ©   (2005-11-25 20:37) [8]

да, наверное вопрос не правильно понял.
извиняй если что :)


 
homm ©   (2005-12-03 19:41) [9]

Может кто-то тогда скажет что такое точно не возможно?


 
Deka ©   (2005-12-05 12:01) [10]

Я тут вот что придумал. Возможно глупость. Контрол обязан перерисоваться после приема сообщения. А если в процедуре приема сообщений при приеме определенной последовательности сообщений менять ее на другую? А при приеме другой - просто пропускать далее? Таким образом наверное удастся контролировать перерисовку.


 
Игорь Шевченко ©   (2005-12-05 12:28) [11]


> Только нужно чтобы было в другой последовательности видно
>  - сначала дети, потом родители.


WS_CLIPCHILDREN у родителя ?


 
homm ©   (2005-12-09 20:09) [12]

SetWindowLong(Panel1.handle, GWL_STYLE,Integer(GetWindowLong(Panel1.handle, GWL_STYLE) and not WS_CLIPCHILDREN ));
Так?
Дети вообще перестают прорисовыватся (даже сообщений нет). Это при разворачивании или переключении через пенель задач. Если затирать перетаскивая другое окно поверх, детей не видно, но они получают соощения примерно в том же порядке (последние сообщения все равно от детей приходят). Пробовал в ВэСэЭль. Инвариантно.


 
Игорь Шевченко ©   (2005-12-09 23:12) [13]

WS_CLIPCHILDREN: Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent
window.

WS_EX_TRANSPARENT: Specifies that a window created with this style is to be transparent. That is, any windows that are beneath the window are not obscured by the window. A window created with this style receives WM_PAINT messages only after all sibling windows beneath it have been updated.


> Нужно чтобы отрисовывались сначала дети


А можно узнать, зачем ?


 
homm ©   (2005-12-10 00:51) [14]


> А можно узнать, зачем ?
Ну что-ж поделюсь предисторией.
В KOL существует понятие прозрачности компонента (кстати ни в одной другой class library (MCK, VCL) нет ничего подобного). Причем прорисовка полностью по идее лежит на библиотеке, пользователю (читать разработчику компонентов и системе) необходимо лиш правильно работать с предоствлеными возможностями. Предлогаемая Владимиром Кладовым реализация мягко говоря глючна и тормознута. Вот я и взялся за написание своей. Используется такой механизм:
1) Ставятся "заглушки", не пропускающие по состоянию флагов WM_PAINT/ERASE в оконную функцию самого компонента.
2) WM_PAINT прозрачного компонента делает Invalidate родителя.
3) Имено родитель, ставя определеные флаги и предоствляя буферизированый контекст говорит дочерним компонентам, что пора перерисовыватся.

На самом деле все гораздо сложнее, но общий принцип такой.

В принципе на данном этапе все работает так, как я того хотел, НО.
При старте приложения и при переключении на панели задач из перекрывающего приложения WM_PAINT отсылается как-то скопом всем контролам, и проблем не возникает.
Если же затереть другим окном часть прозрачного компонента (к App окнам этот метод прозрачности ясно дело не применим), то сообщение WM_PAINT обрабатываются по мере свободного процессорного времени. Вот здесь и возникает заминка в пункте 2). Предположим что были затерты 4 прозрачных компонента. Первым делом обрадатывается WM_PAINT родителя и все перерисовывается превый раз. Затем освобождается свободное процессорное время, и первому из дочерних контролов посылается WM_PAINT, который не обрабатывается в самом контроле (заглушка - пункт 1), но зато посылается Invalidate родителю. WM_PAINT прозрачного компонента обработано, процесорное время появилось и (о чудо) родитель то опять не прорисован (мы же сами Invalidate делали). Снова идет глобальная перерисовка. Итого родитель плюс 4 контрола - 5 раз вся "сцена" рисуется заново. Сразу предвижу вопрос "зачем вообще Invalidate родителя нужен". Готов и ответ: прозрачное окно может быть достаточно большим, и тогда возможно затереть только прозрачное окно, пикселем не трогая родителя. К томуже при Invalidate или пользовательском WM_PAINT прозрачный контрол должен все-же перерисовыватся, а значит и тянуть предка (а в реальной модели даже может не одного с кучей братьев, тётей, племяников).
Теперь допустим удастся осуществить описаное в [0]. Система сразу прогоняет WM_PAINT всех дочерних компонентов, каждый из них вызывает Invalidate для предка, но прорисовка предка (а значит и всей сцены) происходит в последнюю очередь и лишь один раз.

Исходники реализации всего вот этого можно скачать здесь.
http://www.homm86.narod.ru/files/kol222p.zip
Там же в архиве дема есть, можно ее позапускать, посворачивать, позатирать другими окнами, все сразу должно встать на свои места.

ЗЫ
> А можно узнать, зачем ?
Теперь узнали? Спорим вам легче не стало?


 
homm ©   (2005-12-10 06:43) [15]

У меня по ходу появился еще один вопрос.
Вот посылается WM_PAINT родителю. Он перебирает все дочерние компоненты и посылает каждому свой WM_PAINT. Но в любом обработчике WM_PAINT прямо или косвено (через EndPaint например) вызывается Validate! Т.е. после прохода первой прорисовки все дочерние прозрачные контролы ЗАВАЛИДЕЙТКНЫ! И уже после обработки родителя дочерние контролы Инвалидейтятся. Как же так системе удается (или делать вид хлотя бы), что она сначала дожидается окончания прорисовки, а затем инвалидейтит следующий компонент? Причем ведь WM_PAINT действительно посылается лишь при пустой очереди сообщений (читай простое процессора). Такое впечатление что создается очередь Invalidate"ов, следующий элемент из которой зыбирается лиш при обработке продидущего через WM_PAINT. Хотелось бы сразу завалидейтить все компоненты, уже при первой прорисовке родителя.


 
Barloggg   (2005-12-30 10:03) [16]

Обдумывая эту ситуацию не придумал ничего лучше центрального ядра отрисовки с таймером... которое накапливает приходящие сообщения и собственно отрисовку производит по тику таймера. то есть винда пусть присылает свои WM_PAINT, мы есть скажем "ага, примем к сведению" и перебрасываем это в центральное ядро. которое принимает это к сведению но ждет тика таймера. А уж потом оно само раздает всем подотчетным ей контролам приказ на отрисовку.


 
Игорь Шевченко ©   (2005-12-30 10:48) [17]

homm ©   (10.12.05 00:51) [14]


> В KOL существует понятие прозрачности компонента (кстати
> ни в одной другой class library (MCK, VCL) нет ничего подобного).
>  


В VCL. ControlStyle и csOpaque

Но я все равно не понимаю, какова конечная цель. Вероятно, можно найти другое решение, если знать ту самую цель.


> Вот посылается WM_PAINT родителю. Он перебирает все дочерние
> компоненты и посылает каждому свой WM_PAINT. Но в любом
> обработчике WM_PAINT прямо или косвено (через EndPaint например)
> вызывается Validate!


Не посылается. В очереди сообщений после выполнения InvalidateRect одного из окон потока появляется флаг QS_PAINT, у окна, соответственно, тоже появляется соответствующий флаг.

*               The system sends WM_PAINT message when there are no other
*               messages in the application"s message queue. DispatchMessage
*               determines where to send the message; GetMessage determines
*               which message to dispatch. GetMessage returns the WM_PAINT
*               message when there are no other messages in the application"s
*               message queue, and DispatchMessage sends the message to
*               the appropriate window procedure.
*
*               A window may receive internal paint messages as a result of
*               calling RedrawWindow with the RDW_INTERNALPAINT flag set.
*               In this case, the window may not have an update region.
*               An application should call the GetUpdateRect function to
*               determine whether the window has an update region.
*               If GetUpdateRect returns zero, the application should not call
*               the BeginPaint and EndPaint functions.
*               An application must check for any necessary internal painting
*               by looking at its internal data structures for each WM_PAINT
*               message, because a WM_PAINT message may have been caused by
*               both a non-NULL update region and a call to RedrawWindow with
*               the RDW_INTERNALPAINT flag set.
*
*               Windows sends an internal WM_PAINT message only once. After
*               an internal WM_PAINT message is returned from GetMessage or
*               PeekMessage or is sent to a window by UpdateWindow, Windows
*               does not post or send further WM_PAINT messages until
*               the window is invalidated or until RedrawWindow is called again
*               with the RDW_INTERNALPAINT flag set.

*          The BeginPaint function automatically validates the entire client
*          area.
Neither the ValidateRect nor ValidateRgn function should be
*          called if a portion of the update region must be validated before
*          the next WM_PAINT message is generated.



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

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

Наверх




Память: 0.53 MB
Время: 0.044 c
2-1141196983
Urvin
2006-03-01 10:09
2006.03.19
Тормоза Firebird a


9-1126435874
Dgt
2005-09-11 14:51
2006.03.19
Glblur Bugs..


15-1140600431
konrads
2006-02-22 12:27
2006.03.19
Выделить строки кода


15-1140817487
kent
2006-02-25 00:44
2006.03.19
железо


2-1141328178
Golik
2006-03-02 22:36
2006.03.19
Как определить число записей в таблице ? поможите!