获取主题化编辑控件非客户区大小

4
如何获取Windows XP及更高版本中主题化编辑控件的边框(非客户端)宽度?在Windows 7上,使用属性标识符TMT_BORDERSIZE的GetThemeMetric函数对于现有的编辑控件返回0,如果未提供句柄,则返回1。但仔细检查后,应该是2。

当包含WS_VSCROLLWS_HSCROLL窗口样式时,滚动条会在该边框内部绘制,它们确实与控件外缘相隔2像素,因此我认为有一种方法可以获取正确的信息。

查询的原因是为了在创建自定义控件时,在发生WM_NCCALCSIZE时设置客户区域大小。

enter image description here


2
你应该[编辑]你的问题并添加一张图片,显示你所谈论的宽度。 - Jabberwocky
Wine使用GetSystemMetrics(),请参阅我的更新答案。此外,他们在主题编辑中不处理WM_NCCALCSIZE。所有这些可能是为了兼容性原因。如果允许主题更改NC大小,则客户端程序中实际内容的剪辑可能会发生。 - zett42
1个回答

5
如何获取 Windows XP 及更高版本中主题编辑控件的边框(非客户端)宽度?
以下方法适用于所有控件,无论它们是否启用主题,甚至不需要使用主题 API。
1. 调用 `GetClientRect()` 获取客户区域的大小。 2. 调用 `ClientToScreen()` 将客户区矩形转换为屏幕坐标。 3. 调用 `GetWindowRect()` 获取控件包括 NC 区域在内的矩形的屏幕坐标。 4. 计算客户区和窗口矩形坐标之间的差异,以获取边框大小(例如,`leftBorderWidth = clientRect.left - windowRect.left`)。

编辑:

有趣的是,Wine源代码theme_edit.c根本不使用GetThemeMetric()。相反,他们使用SM_CXEDGESM_CYEDGE调用GetSystemMetrics()

在我的系统(Windows 7和Windows 10)上,这将返回正确的值2


我猜这对于所有最邪恶的控件都不起作用,比如组合框。组合框在客户区域内绘制自己的边框! - Anders
我接受这个答案,因为GetSystemMetrics似乎是最接近可用的东西。Wine代码非常有趣,我注意到VirtualTreeView的TBaseVirtualTree在其WMNCPaint中也使用了它。直到有人提供更多与“主题”相关的方法。 - Blurry Sterk

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