如何完全删除窗口的非工作区?

时间:2018-09-20 13:23:10

标签: c++ winapi nonclient-area

我需要一个没有标题栏,没有任何控制框,没有系统菜单且没有框架的窗口(所有功能均由单独的控件提供)。

我怀疑这可能与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_OVERLAPPED0x00000000L

仅提供0并忽略其余部分是行不通的,正如文档所暗示的那样:“窗口是重叠的窗口。重叠的窗口具有标题栏和边框。”

(有趣的是,通过将ControlBox属性设置为False,然后使用{删除标题栏,我完全可以在VB.NET(甚至是VB6)中完成此任务。 {1}},因此我强烈怀疑在VB中可能的情况...)

我将如何用C ++完成任务?


仅在需要Text = ""才能处理不同的消息的情况下,此处为其简约版本:

WindowProc

(使用VS 2017进行编译。)

1 个答案:

答案 0 :(得分: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的大小和位置仅对重叠的窗口有效。对于弹出窗口,必须明确。

根据您的用例,this answer描述的技术可能更适合。使用DWM API,您可以删除非客户区域,但保留阴影,以使窗口从背景中脱颖而出。