【问题标题】:Removing window border?去掉窗口边框?
【发布时间】:2011-01-24 19:40:12
【问题描述】:

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

【问题讨论】:

    标签: winapi getwindowlong setwindowlong


    【解决方案1】:

    下面的 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 调用在所有语言中看起来都是一样的。

    【讨论】:

      【解决方案2】:

      在 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);
      

      【讨论】:

      • @NathanGoings 您能否解释一下为什么您认为这已经过时以及什么是最新的?
      • @RamboNo5: SetWindowLong() 已被 SetWindowLongPtr function() 取代
      • @dns 我明白了,谢谢。但只要您只针对 32 位 Windows,一切都一样。
      • 作为备注,使用 WS_MAXIMIZE 和 WS_MINIMIZE 似乎会在 Windows 10 下将窗口设置为最小化/最大化。您应该将它们替换为 WS_MAXIMIZEBOX 和 WS_MINIMIZEBOX 以避免此问题
      • WS_MAXIMIZEWS_MINIMIZE 影响窗口的初始状态。
      【解决方案3】:

      下面这行代码删除任何给定窗口的边框,只保留它的客户端:

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

      您可以在SetWindowLong 函数的第三个参数中使用WS_POPUPWINDOW。 它还删除了给定窗口的边框并且也可以工作,但不同之处在于它还在窗口的剩余客户端上绘制了 outlined 黑色矩形。该轮廓矩形的厚度为 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,但仍然返回窗口的边框,那么你可以使用SetWindowLong,前两个参数相同,在第三个参数中,你可以使用以下之一:@ 987654333@ 或/和WS_OVERLAPPEDWINDOW 或/和WS_SIZEFRAME

      注意:如果您尝试我的回答,但它对您不起作用,这可能是因为 SetWindowLongGetWindowLong 两个函数都已被取代并且不会为您工作,因为它们与 only 32 位 版本的 Windows 兼容。可能您使用的是 64 位 版本的 Windows,然后改用 SetWindowLongPtrGetWindowLongPtr,它们与 both 32 位64 位 版本的 Windows。 MSDN 在Note 部分中告知了这些功能。只需在该站点中搜索它们即可。以下是它们的链接:

      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

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

      【讨论】:

      • 感谢提醒使用WS_POPUP,这是创建无边框窗口的单一方法。
      【解决方案4】:

      这会删除标题栏和垂直滚动条...

      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;
      }
      

      【讨论】:

      • 你知道怎么去掉边框,但保留标题栏吗?
      • 只使用 ShowScrollBar(hwnd, SB_VERT, FALSE);
      猜你喜欢
      • 2014-08-05
      • 2019-11-28
      • 2011-01-17
      • 1970-01-01
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多