正确的方法来获得Windows控件的首选大小

我需要弄清楚Windows API中控件的首选大小 – 宽度和高度。 据我所知,关于这个问题的唯一官方消息是Windows桌面程序指南的布局页面,这是一个似乎在Windows Vista中引入的文档,以及与Microsoft管理控制台等效的文档 ,前者似乎是基于该文档 。

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

该程序以两种方式计算,均基于此处和此处的信息。 第一个使用TEXTMETRICS结构的tmAveCharWidth字段; 第二个在第一个链接中使用GetTextExtentPoint32()函数。 然后,它重复该过程,考虑古老的System字体(参见第一个链接)。

在Windows 7上运行此程序

  • BUTTON_SIZE_X保持在50(列出的几个东西的宽度)
  • BUTTON_SIZE_Y更改为25(具有一行文本的Vista-and-up-only命令链接的列出高度)

这样我们基于布局页面的预期大小将是75×41的收益率

 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 

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

第二个程序只是创建一个虚拟对话框,并调用MapDialogRect()来获取上面的baseX和baseY坐标 。 这会产生

 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文档都说得太多(或者更糟糕的是,为了使事情尽可能宽;如果这是为了适应对话框,当我试图弄清楚有多宽时,这完全有效首先制作对话框!)。

更重要的是,当微软创建版本6 Common Controls库时,他们决定包含用于确定控件大小的消息! ……只有一些控件:

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

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

所以我想知道的是以下任意组合:

  • 如果“布局”页面上的示例不是,那么五种计算方法中的哪一种是真正正确的?
  • 是否有一个比不完整的布局和MMC布局页面更具权威性的参考控制大小(理想情况下也是起搏)?
  • 是否有这样的参考,早于Vista,也可以提供线索?
  • 或者这一切都是无望的,我不得不挑选一些htat但是看起来不管我怎么了?

只是一些线索:

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

如果启用了visual-style,请使用GetThemePartSize ,否则您需要开发我们的例程来计算首选大小。 请参考Firefox的源代码 。

2.如何布局控件:

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

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

应用程序有许多不同的布局要求,因此android开发了许多布局管理器,如LinearLayout,GridLayout等。因此它适用于Windows UI布局系统和所有其他UI布局系统。

你需要编写很多代码才能做到这一点。 请参考chrome / firefox UI系统的源代码。

3.解决方案:

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