sml писал(а): ↑26.01.2009 11:59
первое, что приходит на мысль, использовать координаты углов окна (если они конечно известны).
Начинаем прорисовку с самого нижнего окна.
Так долго не отвечал, т.к. все это время оч. сильно думал - чуть агрегат не перегрел
Спасибо, информация пригодилась в процессе медитации. Теперь попробую описать здесь общий алгоритм, поскольку: а) Такие сложные вещи с кондачка писать не дело. бэ) Вдруг меня завтра собьет машина скорой помощи? Чтобы можно было подхватить из моих слабеющих рук флаг заботы о виндовом клиенте.

Имеется мнение, что изобретен лисапед. Комментарии приветствуются. Только чур не спрашивать, что я курю
Сначала термины: Область – прямоугольник (Win – RECT, “Lin” – BOX). Регион – список областей (виндовый HRGN).
Исходные: Инфа, которую нужно рисовать в сессии, находится в одной большой битмапе (ShadowDIB). Она отображается в регион, образованный пересечением клиентских областей открытых окон сессии. Каждое окно рисует себя само (обработка WM_PAINT) путем BitBlt из ShadowDIB.
1) Если запрос на прерисовку со стороны х-клиента (внешний), то исходный регион задан списком (непривязанных к окнам!) областей (damage). Обработка события - функция winShadowUpdateGDI -> WindowProc окон, WM_PAINT .
2) Перерисовка может быть запрошена со стороны ОС - операции открытия, изменения размера или положения окна, изменение последовательности окон, открытие, закрытие. Обработка – WindowProc окон, WM_PAINT.
Нужно решить несколько независимых задач, учитывая особенности реализации отображения окон в WinAPI.
1. Для каждого окна сессии поделить клиентскую область на прозрачный регион клиентской области (регион, который отрисовывается непосредственно низлежащими окнами сессии) и регион отрисовки окна РОО (где имеет право рисовать его WindowProc).
Метод: Накопление «снизу». В глоб. переменной накапливаем отображаемый регион сессии (ОРС). Берем весь (а лучше видимый???) регион клиентской обл. (РКО) самого нижнего окна сессии, включаем в ОРС полностью, загоняем в регион отрисовки окна (РОО) весь (а лучше видимый???) РКО.
Далее перебираем все окна, находящиеся выше. Если окно принадлежит сессии, вычисляем РКО, выступающий над ОРС – это будет РОО, расширяем ОРС полученным РОО, исключаем из ОРС и РОО предыдущего окна сессии неклиентский регион текущего окна (???).
Если же вышестоящее окно не принадлежит сессии, то из ОРС исключается регион этого окна, пересекающий ОРС (???).
(то, что помечено вопросами, может быть необязательным для корректной отрисовки, но возможно увеличит быстродействие за счет сужения областей для BitBlt и др?)
2. Внести изменения в текущую обработку «внешней» отрисовки.
Текущий алгоритм: Внешний цикл – перебор damage-областей. Внутренний – перебор окон сессии, вычисление и пометка области отрисовки окна, как пересечения damage с клиентской областью окна (InvalidateRect).
Нужно: Получить из списка damage-областей damage-регион. Для каждого окна сессии получить ранее вычисленный (п.1) регион отрисовки окна (РОО). Пометить регион обновления (InvalidateRgn), равный пересечению РОО с damage-регионом.
3. При более другом запросее (перемещение, изменение размера, всплытие, открытие, закрытие окна) правильным наверное бы было: Накопить ОРС до операции (исключая регион изменяемого окна), затем исходный регион как пресечение ОРС и региона окна до операции, далее получить изменяемый регион, исключив из исходного регион окна после операции. Начиная «снизу», перерисовать в каждом окне сессии регион пересечения РКО и изменяемого региона. В конце отрисовать весь РКО окна.
Что-то сложновато – легче перерисовать весь получившийся после операции ОРС.
А теперь со всей этой ..ней мы попробуем взлететь. (С)