Автор
|
Тема: WS_EX_TRANSPARENT
|
One |
опубликован 15-01-2002 14:20 MSK
Кто-нибудь когда-нибудь юзал subj? Если да, то поделитесь, пж., идеями.Во-первых, когда такое окно накрывается любым другим, то на нем остается его след!??? Избавиться от него не смог никак. Даже отслеживал WM_ACTIVATE и перерисовывал активное окно, но оно почему-то не перерисовывается. Во-вторых, если обработать WM_PAINT так: HDC DC=GetDC(MyWnd); SelectObject(DC, GetStockObject(WHITE_BRUSH)); Rectangle(DC, 50, 50, 150, 150); SelectObject(DC, GetStockObject(BLACK_BRUSH)); Rectangle(DC, 75, 75, 125, 125); ReleaseDC(DC); то имеем: черный прямоугольник сильно мерцает (такое впечатление, что WM_PAINT посылается постоянно), хотя белый показывается нормально.
Короче, или я не прав, либо одно из двух.
|
ADK
|
опубликован 16-01-2002 14:00 MSK
Вроде как M$ советует применять стиль для дочерних окон, чтобы сохранялось и нормально прорисовывалось то, что под ними. Хотя я не вникал. Про 2) - такой код неверен, нельзя так писать, потому что в WM_PAINT прямоугольник обязан стать действительным (validate), иначе WM_PAINT будет слаться снова и снова. Т.е. только BeginPaint и EndPaint, или может, ValidateRect ещё нужен, только я не пробовал. |
clay_pigeon
|
опубликован 16-01-2002 15:43 MSK
На счет мерцания черного и немерцания белого прямоугольников:Все симптомы перерисовки по-умолчанию. Дело в том, что по-умолчанию при перерисовке сначала все закрашивается белым, потом поверх этого рисуется картинка. Отсюда возникает эффект мерцания. Так что белый прямоугольник у тебя тоже мерцает, только с белого на белое. Избежать такого мерцания можно путем манипулирования с флагом a-la ERASE_BKGRND. Например посылая для перерисовки CWnd::Invalidate(false) или RedrawWindow(...) с флагом RDW_NOERASE. |
One
|
опубликован 16-01-2002 17:47 MSK
2 ADK:An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to EndPaint function. {Приложение не должно использовать BeginPaint в ответ на сообщение WM_PAINT. Каждый вызов BeginPaint должен иметь соответсвующий вызов EndPaint} Или я что-то не так понял? Насчет ValidateRect, то да, я согласен. Но все дело в том, что тогда при перемещении окна (в смысле прозрачного) оно теряет свою прозрачность, если в конце обработки писать ValidateRect(hWnd, nil). Ежели такого не писать, то оно остается прозрачным даже при перемещении, но прямоугольник (черный) мерцает. Самое интересное, что если выполнить ValidateRect только для координат, где мы рисуем (т.е. как бы эта область уже больше не должна обновляться), то все равно наблюдается мерцание черного прямоугольника, хотя белый прямоугольник уже становиться статичным (он не мерцает даже при перемещении окна). 2 clay_pigeon: Ни фига подобного. Если не рисовать белый прямоугольник, то черный не мерцает. Вообще, можно даже растр выводить, я пробовал, ничего не мерцает. Вот если поверх этого растра уже что-нибудь нарисовать, то это что-то будет мерцать. И самое интересное. Если не рисовать белый прямоугольник, а ValidateRect писать для его координат, то в прозрачном окне мы увидим буквально следующее: часть фона за координатами белого прямоугольника будет прозрачной даже при перемещении окна, ччасть фона за пределами черного прямоугольника будет первоначально прозрачной, но при перемещении окна он не меняется (т.е. получаем кусок десктопа), и посредине не мерцающий черный прямоугольник. Попробывал отсекать WM_MOVE и писать InvalidateRect с координатами белого прямоугольника, но такое чувство, что это вообще не работает. Насчет мерцания я вообще придумал так, что надо подготавливать конечное изображение в памяти, а потом выводить его уже обчным BitBlt. так не мерцает. |
One
|
опубликован 16-01-2002 17:50 MSK
По поводу первого вопроса, я наверное просто плохо объяснил: Создаю прозрачное окно. Через него все видно, все просто великолепно. Открываею эксплорер (ну или что нибудь другое), так на эксплорере остается все изображение моего прозрачного окна, хотя оно и не активно, и висит позади эксплорера. И главное непонатно, почему. |
tonik
|
опубликован 17-01-2002 03:05 MSK
Проясняю насчёт использования BeginPaint и EndPaint: BeginPaint (и только его) нужно использовать в начале обработки сообщения WM_PAINT, EndPaint (и только его) - после обработки. Эти функции всегда должны использоваться в паре, причём их вызов обязателен, даже если не производится никакой прорисовки. Они нужны, чтобы Windows поставила у себя галочку о том, что окно было перерисовано. Что касается ValidateRect, то его совершенно не нужно использовать при обработки WM_PAINT. |
ADK
|
опубликован 17-01-2002 05:30 MSK
Прозрачность на Win2K и XP можно сделать через layered windows, сейчас все так делают. Может, попробуешь? |
DimaK
|
опубликован 17-01-2002 09:43 MSK
Если цель всего этого кода создание позрачного окна то это делается с помощью региона создаеш замкнутый ломаный контур по внешней части прямоугольник по внутренней огибая все кнопки и прочие элементы. а потом SetWindowRgn( HWND hWnd, // handle to window whose window region is to be set HRGN hRgn, // handle to region BOOL bRedraw // window redraw flag ); именно так делает winamp прозрачным свое окно |
One
|
опубликован 17-01-2002 09:52 MSK
2 tonik: Тогда объясни мне комментарий M$.2 all: Насчет layered windows и регионов я знаю, и как винамп сделать, тоже знаю. Просто хотелось бы выводить растр с помощью альфа канала, а для этого окно должно быть прозрачным, причем в любой системе (от 98-ых). Если кто видел DesktopX, то поймет, о чем я говорю. |
tonik
|
опубликован 18-01-2002 04:16 MSK
Перевожу комментарий M$: An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to EndPaint function. Перевод: Приложение не должно вызывать BeginPaint, кроме как в ответ на сообщение WM_PAINT. Каждый вызов BeginPaint должен иметь соответсвующий вызов EndPaint. Теперь понятно? |
One
|
опубликован 18-01-2002 10:22 MSK
Извините, ошибка в переводе |
DimaK
|
опубликован 21-01-2002 08:33 MSK
назначь NULL_BRUSH окну тогда мерцание пропадет а ws_ex_transparent вообше без NULL_BRUSH не эффективно |