【问题标题】:window border width and height in Win32 - how do I get it?Win32中的窗口边框宽度和高度 - 我如何获得它?
【发布时间】:2010-09-30 16:41:45
【问题描述】:
::GetSystemMetrics (SM_CYBORDER)

...返回 1,我知道标题栏比 ONE 像素高:/

我也试过了:

矩形 r; r.left = r.top = 0; r.right = r.bottom = 400; ::AdjustWindowRect (& r, WS_OVERLAPPED, FALSE); _bdW = (uword)(r.right - r.left - 400); _bdH = (uword)(r.bottom - r.top - 400);

但是边框 w,h 回来为 0。

在我的 WM_SIZE 处理程序中,我需要确保窗口的高度在 “步骤”,例如,一个全新的文本行可以适合窗口 底部没有“垃圾部分行空间”。

但是 ::MoveWindow 需要添加边框空间的尺寸。

之前一定有人这样做过... 感谢您的帮助:)

【问题讨论】:

  • AdjustWindowRect 的文档说,相当无益的是,您不能将 WS_OVERLAPPED 与它一起使用。
  • @JWWalker:实际上,这很有帮助。现在,如果您还知道WS_OVERLAPPED 被定义为0x0,那应该也很明显了。
  • @IInspectable,不,我不知道为什么 WS_OVERLAPPED 为 0 是相关的。

标签: c++ winapi


【解决方案1】:

GetWindowInfo 函数能够返回给定窗口的边框宽度和高度。
cxWindowBorders 成员获取垂直边框宽度,cyWindowBorders 获取水平边框高度。

【讨论】:

    【解决方案2】:
    int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
    

    其实上面的结果可能等于:

    GetClientRect(hWnd, &rcClient); 
    GetWindowRect(hWnd, &rcWind); 
    int border_thickness = ((rcWind.right - rcWind.left) - rcClient.right) / 2; 
    

    GetSystemMetrics(SM_CXSIZEFRAME) 更容易使用。

    【讨论】:

    • 如果不传入 hWnd,GetSystemMetrics 怎么知道你指的是哪个窗口?不同的窗口可以有不同的边框厚度。我认为您的函数检索系统范围的设置。
    【解决方案3】:

    您有另一个解决方案...您可以通过在 WM_CREATE 和 WM_INITDIALOG 消息中调用专用函数来预先计算边界。并在您更改窗口样式或菜单分成两行时刷新值。

    RECT cRect, wRect, oRect;
    GetWindowRect(hWnd, &wRect);
    GetClientRect(hWnd, &cRect);
    MapWindowPoints(hWnd, NULL, (LPPOINT)&cRect, 2);
    
    oRect.left = cRect.left - wRect.left;
    oRect.top = cRect.top - wRect.top;
    oRect.right = wRect.right - cRect.right;
    oRect.bottom = wRect.bottom - cRect.bottom;
    

    【讨论】:

      【解决方案4】:

      GetWindowRectGetClientRect 函数可用于计算所有窗口边框的大小。

      Suite101 在resizing a window and the keeping client area at a know size 上有一篇文章。

      这是他们的示例代码:

      void ClientResize(HWND hWnd, int nWidth, int nHeight)
      {
        RECT rcClient, rcWind;
        POINT ptDiff;
        GetClientRect(hWnd, &rcClient);
        GetWindowRect(hWnd, &rcWind);
        ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
        ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
        MoveWindow(hWnd,rcWind.left, rcWind.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
      }
      

      【讨论】:

      • 有一个 WinAPI 函数可以调整窗口大小以具有给定的客户区大小:AdjustWindowRectEx()
      • 我想我会坚持使用 GetWindowRect() - GetClientRect() 方法。这样我就不必乱搞窗口样式了。这与 GetSystemMetrics(无论如何)会遇到同样的问题......谢谢大家 - 这个地方很摇滚 :)
      • 如果窗口因调整窗口大小而最小化,此解决方案将不起作用
      • 我不认为这种方法适用于 Windows 10,因为透明的 8px 边框允许调整窗口大小。
      【解决方案5】:

      除非窗口最小化或未完全初始化,否则 stukelly 建议的方法将起作用。在这些情况下为您提供边框大小的另一种方法是使用AdjustWindowRectEx 函数。这是一个例子:

      CSize GetBorderSize(const CWnd& window)
      {
         // Determine the border size by asking windows to calculate the window rect
         // required for a client rect with a width and height of 0
         CRect rect;
         AdjustWindowRectEx(&rect, window.GetStyle(), FALSE, window.GetExStyle());
         return rect.Size();
      }
      

      根据应用程序,如果需要当前可见边框大小,则可能需要将此方法与 stukelly 的方法结合使用:

      CSize GetBorderSize(const CWnd& window)
      {
         if (window.IsZoomed())
         {
            // The total border size is found by subtracting the size of the client rect
            // from the size of the window rect. Note that when the window is zoomed, the
            // borders are hidden, but the title bar is not.
            CRect wndRect, clientRect;
            window.GetWindowRect(&wndRect);
            window.GetClientRect(&clientRect);
            return wndRect.Size() - clientRect.Size();
         }
         else
         {
            // Determine the border size by asking windows to calculate the window rect
            // required for a client rect with a width and height of 0. This method will
            // work before the window is fully initialized and when the window is minimized.
            CRect rect;
            AdjustWindowRectEx(&rect, window.GetStyle(), FALSE, window.GetExStyle());
            return rect.Size();
         }
      }
      

      【讨论】:

        【解决方案6】:

        Head Geek 给出了详细的答案:使用 GetSystemMetrics 将标题和边框位相加。您还可以对 GetWindowRect 和 GetClientRect 之间的宽度/高度进行区分。这将为您提供所有字幕/边框/等的总数。

        【讨论】:

        【解决方案7】:

        我认为您正在寻找的是SM_CYCAPTION——这是标题栏的高度。 SM_CYBORDER 是窗口水平边缘的高度。

        【讨论】:

        • 你好。作为我的tool of screen captrue,我知道标题栏的高度是28。但是你的GetSystemMetrics(SM_CYCAPTION) 只给23..
        • 该度量可能包括其他指标,例如窗口边框。
        • 你知道它包含哪些组件吗?
        • 对不起,我没有。
        猜你喜欢
        • 1970-01-01
        • 2014-05-20
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        • 2013-11-29
        • 1970-01-01
        • 2011-10-20
        • 2014-08-28
        相关资源
        最近更新 更多