Форум: "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.016 c