Как я могу полностью удалить неклиентскую область окна? - PullRequest
0 голосов
/ 20 сентября 2018

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

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

0 голосов
/ 21 сентября 2018

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

...