Win32: Как нарисовать за пределами моего окна? - PullRequest
4 голосов
/ 10 февраля 2010

Глядя на окно подсказки класса Windows tooltips, я вижу, что оно рисует свою тень вне фактического прямоугольника окна подсказки.

Использование SpyXX - я могу получить прямоугольник окна всплывающей подсказки и стили классов:

image

Rectangle:     (440, 229)-(544, 249), 104x20
Restored Rect: (440, 229)-(544, 249), 104x20
Client Rect:   (0, 0)-(104, 20), 104x20

You'll notice that the drop shadow you see is physically outside the window that's being drawn. How can i draw a shadow outside around my window, while being outside my window?

Note: Тень не рисуется с использованием стандартного стиля класса CS_DROPSHADOW. Я подтвердил это экспериментально, и также могу увидеть стиль класса для окна в SpyXX ; он не использует CS_DROPSHADOW:

Windows Styles:     94000001

    WS_POPUP        80000000
    WS_VISIBLE      10000000
    WS_CLIPSIBLINGS  4000000
    TTS_ALWAYSTIP          1

Extended Styles:    00080088

    WS_EX_LAYERED      80000
    WS_EX_TOOLWIN         80
    WS_EX_TOPMOST          8

Так как я могу рисовать за окном?

Примечание: Попытка нарисовать на рабочем столе DC не работает. Из Грега Шехтера, перенаправляющего приложения GDI, DirectX и WPF :

Рисование и чтение с экрана - Баааад!

Наконец, так как мы находимся на перенаправлении тема, особенно опасная практика пишет на экране, либо с помощью GetDC (NULL) и писать на это, или пытаясь делать XOR-тесьмы и т. д. две большие причины, по которым экран плохой:

Это дорого ... писать в сам экран не дорогой, но это почти всегда сопровождается чтение с экрана, потому что один обычно делает чтение-изменение-запись такие операции, как XOR при записи в экран. Чтение из видео поверхность памяти очень дорогая, требует синхронизации с DWM, и останавливает всю трубу GPU, как а также канал приложения DWM.
Это непредсказуемо ... если ты как-то удалось добраться до фактического начального и пиши в него, там не может быть предсказуемость относительно того, как долго вы написал первичному останется на экран. Поскольку UCE не знает об этом, это может быть очищено в обновление следующего кадра, или оно может сохраняться в течение очень долгого времени, в зависимости от что еще нужно обновить на экран. (Мы действительно не разрешаем прямой в любом случае, писать в основной эта самая причина ... если вы попытаетесь получить доступ к основному DirectDraw, для Например, DWM отключится до выходящее приложение выходит)

Ответы [ 3 ]

5 голосов
/ 10 февраля 2010

Вы не можете рисовать за окном так, как вы описываете.

Если вы щелкнете правой кнопкой мыши по своему рабочему столу, перейдите в свойства / внешний вид / эффекты и снимите флажок «Показать тени под меню» ... у вас больше не будет тени.

Суть в том, что это продукт оконного менеджера, а не вашей программы.

3 голосов
/ 07 января 2013

В: Как вы рисуете за пределами одного окна? A: Нарисуйте внутри другое окно!

Первое, что нужно отметить, это то, что класс всплывающей подсказки действительно использует стиль CS_DROPSHADOW - но учтите, что это стиль class , а не окно style, поэтому вам нужно взглянуть на вкладку Class в диалоге свойств Spy ++, чтобы найти ее. Вы увидите, что окна tooltips_class32 действительно имеют это - и некоторые другие.

Но это только приводит к следующему вопросу - как это работает? Что ж, похоже, что Windows реализует это, создавая вспомогательный HWND для рисования тени - предположительно, он создает другое всплывающее окно того же размера и формы, что и затененное, заполняет его серым, помещает его непосредственно под главное окно и устанавливает это как WS_EX_LAYERED окно, так что тень может быть прозрачной и исчезать по краям, используя альфа-смешение. И ничто не мешает вам использовать те же или похожие методы самостоятельно, если вы хотите добавить другой тип эффекта тени к одному из своих окон.

Итак, короткая история: если вы хотите рисовать вне своего собственного окна, создайте прозрачное вспомогательное окно в общей области, на которой вы хотите рисовать, и вместо этого нарисуйте это вспомогательное окно.

-

Теперь, если вы попытаетесь найти одно из этих вспомогательных теневых окон в Spy ++, вы не найдете много. В отличие от окон tooltip_class32, которые являются долгоживущими и просто скрывают / показывают себя по мере необходимости, эти теневые окна являются более неуловимым существом: они создаются только столько времени, сколько необходимо, поэтому вам придется обновлять Spy ++, пока есть всплывающая подсказка или всплывающее меню или другое окно, в котором используется тень - и это сложно, поскольку большинство подсказок и меню исчезают, как только вы перемещаете мышь, чтобы переключиться на Spy ++. Но оказывается, что всплывающие подсказки на собственной панели инструментов Spy ++: запустите Spy ++, наведите курсор мыши на элемент на панели инструментов и нажмите F5, чтобы обновить дерево HWND, пока присутствуют подсказка и тень. Теперь прокрутите вниз, и вы увидите, что третий и четвертый видимые HWND в дереве - это сама всплывающая подсказка, а сразу после этого окно SysShadow. К сожалению, поскольку всплывающая подсказка и тень к настоящему времени исчезли, если вы попытаетесь открыть диалоговое окно свойств для этого HWND, вы получите пустое диалоговое окно свойств с сообщением «Неверное окно». Если вы действительно хотите поэкспериментировать и посмотреть, как работает этот SysShadow, какие стили он сам использует и т. Д., Вы можете создать целевое приложение с долгоживущим всплывающим окном, использующим CS_DROPSHADOW, которое затем можно исследовать в Spy ++ на досуге.

(Наконец, обратите внимание, что эти тени - это нечто совершенно иное, чем тени, которые вы видите, когда одно окно приложения находится поверх другого над другим с Vista: этот тип тени является частью режима Aero Glass и обрабатывается тот же Desktop Composition Manager , который добавляет эффект стеклянного заголовка, и он не использует или не нуждается во вспомогательных окнах для реализации теней.)

1 голос
/ 10 февраля 2010

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

...