如何在Windows中获取窗口的默认标题栏高度?

5
我正在开发一个应用程序,它采用了自绘制标题栏,需要模仿系统默认标题栏。
那么我如何获取Windows中重叠窗口的默认标题栏高度呢?
2个回答

12

从Firefox移植的源代码:

// mCaptionHeight is the default size of the NC area at
// the top of the window. If the window has a caption,
// the size is calculated as the sum of:
//      SM_CYFRAME        - The thickness of the sizing border
//                          around a resizable window
//      SM_CXPADDEDBORDER - The amount of border padding
//                          for captioned windows
//      SM_CYCAPTION      - The height of the caption area
//
// If the window does not have a caption, mCaptionHeight will be equal to
// `GetSystemMetrics(SM_CYFRAME)`
int height = (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION) +
    GetSystemMetrics(SM_CXPADDEDBORDER));
return height;

注:高度取决于dpi。


1
在不同的DPI缩放设置下测量实际标题栏大小似乎比我预期的要困难一些(例如,通过DPI/96.0f进行乘法运算)。我得出了这个公式:std::ceil( ((GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME)) * dpi_scale) + GetSystemMetrics(SM_CXPADDEDBORDER) ) - melak47
1
GetSystemMetricsForDpi - Charles Milette

5

一个解决方案是使用 AdjustWindowRectEx 函数,该函数还计算其他窗口边框的宽度,并允许窗口样式的变化:

RECT rcFrame = { 0 };
AdjustWindowRectEx(&rcFrame, WS_OVERLAPPEDWINDOW, FALSE, 0);
// abs(rcFrame.top) will contain the caption bar height

对于现代的 Windows(10+),有适用于 DPI 的版本:

// get DPI from somewhere, for example from the GetDpiForWindow function
const UINT dpi = GetDpiForWindow(myHwnd);
...
RECT rcFrame = { 0 };
AdjustWindowRectExForDpi(&rcFrame, WS_OVERLAPPEDWINDOW, FALSE, 0, dpi);
// abs(rcFrame.top) will contain the caption bar height

这个答案非常有帮助。如需了解更多关于 DPI 的信息,请参阅 Microsoft 在 GitHub 上的代码示例:https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/DPIAwarenessPerWindow/client/DpiAwarenessContext.cpp#L241 - kevinarpe

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