如何完全删除窗口的非客户区? [英] How can I remove a window's non-client area completely?

查看:33
本文介绍了如何完全删除窗口的非客户区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个没有标题栏、没有控制框、没有系统菜单和没有框架的窗口(所有这些功能都由单独的控件提供).

我怀疑这应该可以通过 CreateWindowExA 的窗口样式参数 dwStyle 和可能的 lpWindowName 来实现,如下所述:https://docs.microsoft.com/en-us/windows/desktop/winmsg/window-styles

I suspect that this should be possible to do with CreateWindowExA's window styles argument dwStyle and possibly lpWindowName, as described here: https://docs.microsoft.com/en-us/windows/desktop/winmsg/window-styles

这就是参数最初的样子:

This is how the arguments look like originally:

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被定义为

However, in dwStyle, the normal window style WS_OVERLAPPEDWINDOW is defined as

WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX

WS_OVERLAPPED0x00000000L.

简单地提供 0 并省略其余部分是行不通的,正如文档所暗示的那样:该窗口是一个重叠窗口.重叠窗口有一个标题栏和一个边框."

Simply providing 0 and omitting the rest doesn't work, as also the documentation implies: "The window is an overlapped window. An overlapped window has a title bar and a border."

(有趣的是,通过将 ControlBox 属性设置为 False 然后我完全能够在 VB.NET(甚至在 VB6)中完成此任务通过使用 Text = "" 删除标题栏,所以我强烈怀疑在 VB 中可能的话...)

(The funny thing is, I am perfectly able to do this task in VB.NET (and even in VB6) by setting the ControlBox property to False and then by removing the titlebar using Text = "", so I strongly suspect that when possible in VB...)

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

以防万一需要 WindowProc 来处理不同的消息,这里是它的简约版本:

Just in case the WindowProc is needed in order to process a different message, here it is in its minimalistic version:

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 编译.)

(Compiling with VS 2017.)

推荐答案

仅使用 WS_POPUP 样式即可删除顶级窗口的非客户区:

The non-client area of a top-level window can be removed by using only the WS_POPUP style:

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 的大小和位置仅对重叠窗口有效.对于弹出窗口,您必须明确.

Note that CW_USEDEFAULT for size and position is only valid for overlapped windows. For popup windows you have to be explicit.

根据您的用例,这个答案描述的技术可能更合适.使用 DWM API,它允许您删除非客户区,但保留阴影以使窗口更好地从背景中突出.

Depending on your use case, the technique described by this answer might be better suitable. Using the DWM API, it allows you to remove the non-client area, but keep the drop shadow to make the window stand out better from the background.

这篇关于如何完全删除窗口的非客户区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆