Мне нужно окно без заголовка, без блоков управления, без системного меню и без рамок (все эти функции обеспечиваются отдельными элементами управления).
Я подозреваю, что это должно быть возможно сделать с CreateWindowExA
Аргумент стиля окна dwStyle
и, возможно, lpWindowName
, как описано здесь: https://docs.microsoft.com/en-us/windows/desktop/winmsg/window-styles
Вот как выглядят аргументы изначально:
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class.
L"", // No window name (title text).
WS_OVERLAPPEDWINDOW, // Window style.
// Size and position.
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window.
NULL, // Menu.
hInstance, // Instance handle.
NULL // Additional application data.
);
Однако в dwStyle
, нормальный стиль окна WS_OVERLAPPEDWINDOW
определяется как
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
с WS_OVERLAPPED
являющийся 0x00000000L
,
Простое указание 0 и пропуск остальных не работает, так как из документации следует: «Окно является перекрывающимся окном. Перекрытое окно имеет строку заголовка и границу».
(Самое смешное, что я вполне могу выполнить эту задачу в VB.NET (и даже в VB6), установив ControlBox
собственность на False
а затем, удалив заголовок с помощью Text = ""
, поэтому я сильно подозреваю, что при возможности в VB …)
Как бы я сделал свою задачу в C ++?
На всякий случай WindowProc
необходим для обработки другого сообщения, вот в его минималистической версии:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
(Сборник с VS 2017.)
Неклиентскую область окна верхнего уровня можно удалить, используя только WS_POPUP
стиль:
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class.
L"", // No window name (title text).
WS_POPUP, // Window style.
// Size and position.
100, 100, 400, 300,
NULL, // Parent window.
NULL, // Menu.
hInstance, // Instance handle.
NULL // Additional application data.
);
Обратите внимание, что CW_USEDEFAULT
размер и положение действительны только для перекрывающихся окон. Для всплывающих окон вы должны быть явными.
В зависимости от вашего варианта использования, методика, описанная этот ответ может быть лучше подойдет. Используя DWM API, он позволяет удалить не клиентскую область, но держать тень чтобы окно выделялось лучше на заднем плане.
Других решений пока нет …