C++ Win32 中的窗口边框宽度和高度 - 我如何获得它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/431470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:19:08  来源:igfitidea点击:

window border width and height in Win32 - how do I get it?

c++winapi

提问by Stephen Hazel

      ::GetSystemMetrics (SM_CYBORDER)

...comes back with 1 and I know the title bar is taller than ONE pixel :/

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

I also tried:

我也试过:

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

But border w,h came back as 0.

但是边界 w,h 返回为 0。

In my WM_SIZE handler, I need to make sure the window's height changes in "steps" so, for example a whole new line of text could fit in the window with no "junky partial line space" at the bottom.

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

But ::MoveWindow needs the dimensions WITH the border space added in.

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

SOMEbody must have done this before... Thanks for any help :)

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

回答by stukelly

The GetWindowRectand GetClientRectfunctions can be used calculate the size of all the window borders.

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

Suite101 has a article on resizing a window and the keeping client area at a know size.

Suite101 有一篇关于调整窗口大小和将客户区保持在已知大小的文章

Here is their sample code:

这是他们的示例代码:

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

回答by Tody.Lu

int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);

In fact, the above result might be equal to:

事实上,上面的结果可能等于:

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

but GetSystemMetrics(SM_CXSIZEFRAME)is easier to be used.

GetSystemMetrics(SM_CXSIZEFRAME)更容易使用。

回答by Head Geek

I think what you're looking for is SM_CYCAPTION-- that's the height of the title bar. SM_CYBORDERis the height of the horizontal edges of a window.

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

回答by Thomas M

The method suggested by stukelly will work unless the window is minimized or not fully initialzied. An alternate approach that will give you the border size in these conditions is to use the AdjustWindowRectExfunction. Here is an example:

除非窗口最小化或未完全初始化,否则 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();
}

Depending on the application, it may be necessary to combine this approach with stukelly's if the current visible border size is necessary:

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

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

回答by Thomas M

Head Geek gives the detailed answer: use GetSystemMetrics to add up the caption and border bits. You can also do a difference on width/height between the GetWindowRect and GetClientRect. This will give you the total of all captions/borders/etc.

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

回答by Thomas M

You have another solution... You can pre calculate the border by calling a dedicated function while in WM_CREATE and WM_INITDIALOG messages. And refresh the values when you change your window style or when menu split in two rows.

您有另一个解决方案...您可以通过在 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;