去掉窗口边框?

33

我有一个周围带实线边框的窗口。如何使用SetWindowLongGetWindowLong删除边框(所有非客户区)?

4个回答

59
在C/C++中
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
SetWindowLong(hwnd, GWL_STYLE, lStyle);

WS_CAPTION被定义为(WS_BORDER | WS_DLGFRAME)。当标题栏消失时,您可以只删除这两种风格,因为最小化、最大化和系统菜单也将消失,但最好也将它们删除。

最好还要删除扩展边框风格。

LONG lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);

最后,为了让您的窗口以更改后的样式重新绘制,您可以使用SetWindowPos。

SetWindowPos(hwnd, NULL, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);

3
@NathanGoings 您能否解释一下为什么您认为这已经过时,并说明最新的替代方案是什么? - RamboNo5
9
SetWindowLong()函数已被SetWindowLongPtr()函数取代。 - dns
4
@dns 我明白了,谢谢。但只要你的目标是32位Windows,那就没区别了。 - RamboNo5
1
作为一种提醒,使用WS_MAXIMIZE和WS_MINIMIZE在Windows 10下会导致窗口出现故障,使其状态为最小化/最大化。 您应该将它们替换为WS_MAXIMIZEBOX和WS_MINIMIZEBOX以避免此问题。 - user780756
WS_MAXIMIZEWS_MINIMIZE 影响窗口的初始状态。 - NathanAldenSr
1
如何恢复边框?有什么想法吗? - KeyC0de

11

以下是 Delphi 代码:

  SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) and not WS_BORDER and not WS_SIZEBOX and not WS_DLGFRAME );
  SetWindowPos(Handle, HWND_TOP, Left, Top, Width, Height, SWP_FRAMECHANGED);

当然,所有语言中这些API调用看起来都是相同的。


8

下面这行代码可以移除任何窗口的边框,只保留其客户区域:

SetWindowLong(hWnd /*The handle of the window to remove its borders*/, GWL_STYLE, WS_POPUP);

您可以在SetWindowLong函数的第三个参数中使用WS_POPUPWINDOW代替。它也会移除给定窗口的边框,并且同样有效,但不同之处在于它还会在剩余客户端上绘制一个轮廓黑色矩形。该轮廓矩形的厚度为1像素。WS_POPUP不会绘制该矩形,实际上它什么也不绘制,只是移除窗口的边框。

如果您想要恢复窗口的边框,在使用我上面发布的代码行之前,请先调用以下代码行:

GetWindowLong(hWnd /*The handle of the window that you want to remove its borders and later return them back to it*/, GWL_STYLE);

当然,这个函数返回的是窗口的样式,因此创建一个新变量来保存这些样式,即将该变量设置为该函数的返回值。

然后像我上面展示的那样使用SetWindowLong来去掉窗口的边框,当您稍后想要恢复其边框时,只需再次调用SetWindowLong,前两个参数相同(hWnd和GWL_STYLE),但第三个参数是从GetWindowLong返回的窗口样式。如果您不想调用GetWindowLong,但仍要返回窗口的边框,则可以在第三个参数中使用以下之一:WS_OVERLAPPED或/和WS_OVERLAPPEDWINDOW或/和WS_SIZEFRAME

注意:如果您尝试我的答案,但它对您无效,可能是因为SetWindowLongGetWindowLong这两个函数已经被取代,不再适用于您的操作系统。这是因为它们只兼容32位的Windows版本。可能您正在使用64位的Windows版本,那么请改用SetWindowLongPtrGetWindowLongPtr,它们兼容32位和64位的Windows版本。MSDN在注释部分中有关于这些函数的说明。只需在该网站上搜索即可找到它们。以下是它们的链接:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms633584(v=vs.85).aspx

希望这一切回答了你的问题。


1
谢谢提醒使用WS_POPUP,它是创建无边框窗口的唯一方法。 - weaknespase

1
这将移除标题栏和垂直滚动条...
int main()
{
    HWND hwnd = GetConsoleWindow();
    // remove title bar
    LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
    lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
    SetWindowLong(hwnd, GWL_STYLE, lStyle);
    //remove vertical scrollbar
    ShowScrollBar(hwnd, SB_VERT, FALSE);

    cout << "Hello World! \n";
    system("pause");

    return 0;
}

你知道如何去掉边框,但保留标题栏吗? - Emile
只需使用 ShowScrollBar(hwnd, SB_VERT, FALSE); 即可。 - pollaris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接