【问题标题】:Proper way to get the preferred size of Windows controls获得 Windows 控件首选大小的正确方法
【发布时间】:2014-07-30 14:23:23
【问题描述】:

我需要确定 Windows API 中控件的首选大小(宽度和高度)。据我所知,关于此事的唯一官方说法是the Layout page of the Windows Desktop Program Guidelines,一个似乎是随 Windows Vista 引入的文档,以及Microsoft Management Console docs equivalent,前者似乎是基于此。

前一页给出了对话框单位和像素的示例尺寸(后一页中没有!)表面上是针对 96 dpi 的 9 点 Segoe UI。我不知道对话单元计算是否从未针对这个新的 DPI 值进行更新,但无论如何,我尝试了三种不同的方法,但没有准确的加起来。

This program 以两种方式计算,均基于信息herehere。第一种使用TEXTMETRICS结构的tmAveCharWidth字段;第二个使用第一个链接中的GetTextExtentPoint32() 函数。然后,它重复这个过程,考虑到古老的系统字体(见第一个链接)。

在 Windows 7 上运行此程序

  • BUTTON_SIZE_X 保持在 50(列出的几个东西的宽度)
  • BUTTON_SIZE_Y 更改为 25(仅包含一行文本的 Vista 及以上命令链接的列出高度)

这样我们基于布局页面的预期尺寸将是 75x41 产量

GetTextExtentPoint32: Segoe UI 9 | baseX 7 baseY 15 | button 50 x 25 -> 88 x 47
tm.tmAveCharWidth:    Segoe UI 9 | baseX 6 baseY 15 | button 50 x 25 -> 75 x 47
with system font: System 9
GetTextExtentPoint32: Segoe UI 9 | cX 7 cY 15 sysX 8 sysY 16 | button 50 x 25 -> 87 x 46
tm.tmAveCharWidth:    Segoe UI 9 | cX 6 cY 15 sysX 7 sysY 16 | button 50 x 25 -> 85 x 46

我们已经可以看到从对话框单位到像素的四种不同可能的转换。

The second program 只是创建一个虚拟对话框并调用MapDialogRect() 来获取the baseX and baseY coordinates in the above。这会产生

Segoe UI 9 weight:400 italic:0 charset:1
[0 0 8 16]

如果我们手动进行第一个程序所做的计算:

width  - (50*8)/4 = 100
height - (25*16)/8 = 50

我想知道是否所有的计算(包括用于命令链接的计算)都使用了 Tahoma 或 MS Sans Serif,Vista 之前使用的字体......但是我不知道正确的大小是多少!

这仍然会留下没有列出宽度或宽度公式的复选框和静态文本控件(以及命令链接!)等控件。当然,对于静态文本控件,我可以只获取文本的宽度并说这是首选宽度,但这并未考虑控件提供的任何可能的水平填充。这不适用于复选框,复选框部分有额外的宽度。 (我确实找到了一些方法来找到这些坐标,特别是在 Stack Overflow 上,但它们都有其缺点)。甚至我在这个问题顶部提到的 MMC 文档也没有说太多(或者更糟糕的是,使事情尽可能宽;如果这是为了适合对话框,那么当我试图弄清楚首先制作对话框!)。

更重要的是,当 Microsoft 创建第 6 版通用控件库时,他们决定包含用于确定控件适当大小的消息! ...只有一些控件:

  • BCM_GETIDEALSIZE - 按钮;列为对其他类型的按钮无效
  • DTM_GETIDEALSIZE - 日期/时间选择器
  • LM_GETIDEALSIZE - 超链接; 只返回给定宽度的高度
  • RBBIM_IDEALSIZE - ReBar 控件;实际上不是消息,而是其他东西
  • TB_GETIDEALSIZE - 工具栏

现在如何与 Windows 中的控件进行比较?好吧,在 Windows XP 上,一切看起来确实是正确的,但是 Winodws 7 的对话框和其他控件非常不一致(有些仍然使用 Tahoma 甚至 MS Sans Serif 作为对话框字体!)而且我永远无法确定什么按钮大小是正确的。

所以我想知道的是:

  • 五种计算方法中哪一种是真正正确的,如果 Layouts 页面上的示例不正确?
  • 与不完整的 Layout 和 MMC Layout 页面相比,是否有关于控件大小(以及理想情况下的节奏)更权威的参考?
  • 在 Vista 之前是否有这样的参考资料也可以提供线索?
  • 或者这一切都是没有希望的,我必须选择一些对我来说看起来不对的东西?

【问题讨论】:

  • 请给问题起一个对其他人有意义的标题。
  • 你能给出一个你需要知道的理由吗?您是否尝试复制当前控件并稍作更改?
  • 否;这专门用于手动控件创建和布局。
  • 正如您所指出的,Windows 用户界面一团糟。因为“绝望”而让我失望。
  • 因此根据“Microsoft Windows 用户体验:用户界面开发人员和设计师的官方指南”(1999),对话单元计数没有改变;这本书没有提供样本像素数,但我开始倾向于“它仍然基于 Tahoma/MS Sans Serif 字体,或者至少是该字体中的 Segoe UI”。我可以稍后再试...

标签: c winapi user-interface


【解决方案1】:

只是一些线索:

1.要获得首选大小的窗口控件:

如果视觉样式打开,请使用GetThemePartSize,否则您需要开发我们的例程来计算首选尺寸。请参考火狐的source code

2.如何布局控件:

或如何确定控件的正确大小和正确位置。这不是一个简单的问题,您需要像其他 UI 系统一样开发自己的布局管理系统。以安卓为例,

  1. 它需要根据当前窗口的大小和它自己的布局参数(fixed-size/fill-parent/warp-content)来测量控件的大小。对于文本按钮,它需要测量文本的大小。
  2. 如果所有子大小的总和超出窗口大小,则需要进行一些协调。
  3. 最后为控件设置正确的大小和位置。

一个应用程序有很多不同的布局需求,所以android开发了很多布局管理器,比如LinearLayout、GridLayout等。Windows UI布局系统和所有其他UI布局系统也是如此。

您需要编写大量代码才能做到这一点。请参考chrome/firefox UI系统源码。

3.解决办法:

我认为你最好使用一些现有的UI系统如QT/Vxwidgets来做Windows控件布局。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多