Как я могу полностью удалить неклиентскую область окна?

Мне нужно окно без заголовка, без блоков управления, без системного меню и без рамок (все эти функции обеспечиваются отдельными элементами управления).

Я подозреваю, что это должно быть возможно сделать с 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.)

1

Решение

Неклиентскую область окна верхнего уровня можно удалить, используя только 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, он позволяет удалить не клиентскую область, но держать тень чтобы окно выделялось лучше на заднем плане.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]