Подтвердить что ты не робот

Окно без полей с использованием привязки Areo, тени, минимизации анимации и встряхивания

Я делаю приложение с окном без полей в Windows. Однако, поскольку окно без полей, у меня нет тени теней, оснастки, минимизации анимации или тряски. Я огляделся и не нашел ни одного сайта, объясняющего, как это реализовать. Однако я знаю, что это возможно, потому что Office 2013, Visual Studio 2012 и Steam имеют эти функции и безграничны. Я специально использую QT и С++, но если вы решили это для другой библиотеки окон, я также хотел бы услышать ваши решения. или. И по тенью теней я не имею в виду тень с двух сторон, я имею в виду светящуюся тень со всех сторон всех активных приложений на окнах windows.

4b9b3361

Ответ 1

После использования Spy ++ для проверки окна Steam (его стили окна, ответы на сообщения окна) и попытки сопоставить все, что он делает, в сочетании с вызовами DWMAPI из этого С# без полей поведение окна, я считаю, что я понял это.

Чтобы скрыть границу окна, обработайте сообщение WM_NCCALCSIZE в вашем WindowProc:

case WM_NCCALCSIZE:
    {
        if (window->is_borderless) return 0;
        else return DefWindowProc(hwnd, msg, wparam, lparam);
    }

Чтобы включить тень, все, что вам нужно сделать, это:

MARGINS borderless = {1,1,1,1};
DwmExtendFrameIntoClientArea(hwnd, &borderless);

Чтобы отключить его, восстановите значения по умолчанию MARGINS windowed = {0,0,0,0};. Возможно, запустите также SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE );, чтобы убедиться, что кадр перерисовывается.

Однако, похоже, что это не работает со всеми стилями окна, , очевидно, что ваш стиль окна не должен содержать заголовков. Строки заголовков работают нормально, а добавление одного позволяет включить анимацию минимизации.

Простейший стиль окна, с которым я работал, был тэгом WS_POPUP | WS_THICKFRAME, чтобы получить аэробную привязку, максимизацию, минимизацию и анимацию с минимальным уменьшением. Я использовал WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION.

Изменение DWMWA_NCRENDERING_POLICY или DWMWA_ALLOW_NCPAINT через DwmSetWindowAttribute не представляется обязательным, настройки по умолчанию, похоже, работают.

Одно слово предостережения: DwmExtendFrameIntoClientArea делает именно то, что предлагает название, поэтому, если вы рисуете изображение с альфа-каналом прямо в своей клиентской области (скажем, с opengl, direct3d/2d), будет отображаться небольшой кадр через него:

borderless window with shadow and frame showing in client area

Таким образом, вам может понадобиться поместить непрозрачный виджет, кисть или что-то за прозрачным элементом.

Если все пойдет хорошо, оно должно выглядеть следующим образом:

enter image description here

Вот небольшой проект, F11 переключает режим без полей/окон, F12 включает и выключает тень без рамки.

Ответ 2

Спасибо melak47 за ваш ответ.

Для людей, которые ищут пример С++/Qt, этот профиль GitHub делает работу как шарм (благодаря deimos1877) на основе кода melak47! https://github.com/deimos1877/BorderlessWindow

Обязательно используйте Visual Studio компилятор ( >= 2010), чтобы получить нужную DLL, и он должен работать. Этот пример включает поддержку аэроснимков, окно без полей, минимизацию эффекта, аэродинамические тени.