Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.013 c
2-1141062648
redlord
2006-02-27 20:50
2006.03.19
message+ Tthread


15-1140721369
ArtemESC
2006-02-23 22:02
2006.03.19
Иконки Delphi...


15-1140194509
wicked
2006-02-17 19:41
2006.03.19
занятная геометрия.... черезчур....


2-1141574177
Музыкант
2006-03-05 18:56
2006.03.19
Как написать пианино?


2-1140208811
Saimon
2006-02-17 23:40
2006.03.19
Как добиться в дельфи, чтобы форма была на уровне рабочего...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский