Я делаю приложение с окном без полей в Windows. Однако, поскольку окно без полей, у меня нет тени теней, оснастки, минимизации анимации или тряски. Я огляделся и не нашел ни одного сайта, объясняющего, как это реализовать. Однако я знаю, что это возможно, потому что Office 2013, Visual Studio 2012 и Steam имеют эти функции и безграничны. Я специально использую QT и C++, но если вы решили это для другой библиотеки окон, я также хотел бы услышать ваши решения. или. И по тенью теней я не имею в виду тень с двух сторон, я имею в виду светящуюся тень со всех сторон всех активных приложений на окнах windows.Окно без полей с помощью Areo Snap, Shadow, Minimize Animation и Shake
ответ
После использования Spy ++ для проверки окна Steam (его стили окна, ответы на сообщения в окне) и попытки сопоставить все, что он делает, в сочетании с вызовами DWMAPI от этого C# borderless window behavior, я считаю, что я понял это.
Чтобы скрыть границу окна, обрабатывать 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), небольшой кадр будет виден через это:
Таким образом, вы, возможно, придется поставить непрозрачный виджет, кисть или что-то позади прозрачного элемента.
Если все идет хорошо, он должен выглядеть следующим образом:
Here is a small example project, F11 переключает без полей/оконный режим, F12 переключает без границ тени и выключаться.
Steam по-прежнему имеет тень, идентичную тени Aero. Он также имеет Aero Snap/Shake/Stuff, но не хватает анимации минимума. – Keavon
@RandomUser Мое решение делает все, кроме минимизирующего перехода - результат стиля окна, необходимый для работы тени. Даже в Outlook 2013 этого недостаточно, поэтому я не считаю, что это возможно, не притворяясь, как Visual Studio делает свое свечение. (иногда вы можете видеть, что рамка окна становится видимой внутри области «клиент» - поэтому они действительно появляются, чтобы рисовать над фреймом) – melak47
Сведение к минимуму анимации Visual Studio похоже на окно с рамкой. Неужели они просто отлично справились с этим? Любая идея, как мы могли бы это сделать? – Keavon
Спасибо melak47 за ваш ответ.
Для людей, которые ищут пример C++/Qt, этот профиль GitHub делает работу как шарм (благодаря deimos1877) на основе кода melak47! https://github.com/deimos1877/BorderlessWindow
Обязательно используйте Visual Studio компилятор (> = 2010), чтобы получить нужную DLL, и он должен работать. Этот пример включает поддержку аэроснимков, окно без полей, минимизацию эффекта, аэродинамические тени.
Я бы хотел сказать, что это лучший ответ, надеюсь, что новые люди придут сюда, чтобы использовать эту демонстрацию. – lygstate
С Qt5.8 вы получаете ошибку компилятора в 'qwinhost.cpp' в строке 257, жалуясь на то, что не найден идентификатор' qWinAppInst() '. 'qWinAppInst()' был удален из QtCore в Qt5.8 (см. [здесь] (https://github.com/qtproject/qt-solutions/commit/master)), поэтому вам нужно заменить его на 'GetModuleHandle (0) ' – user2366975
Я не сказал нисходящее направление, я просто хочу сказать вам, что ссылки должны быть только поддерживающими, потому что, если ссылка сломана, ваш ответ становится бесполезным – eyllanesc
Ваше предположение, что они без границ просто неправильно. Программы VS2012 и Office 2013, конечно же, не являются тем, что вы можете видеть со Spy ++. Я предполагаю, что DwmSetWindowAttribute(), DWMWA_ALLOW_NCPAINT в частности. –
Я прочитал на DWMWA_ALLOW_NCPAINT. Итак, слово 2013 и VS2012 нарисовать поверх границы, чтобы скрыть это? –
Не знаю, это просто догадка. Вы должны спросить программиста, который работал над этим, низкие шансы, что вы найдете его здесь и готовы поделиться. –