C语言 正确的方式来获得首选的Windows控件的大小



我需要找出Windows API中控件的首选大小-宽度和高度。据我所知,关于这个问题的唯一官方说法是Windows桌面程序指南的布局页面,该文档似乎是与Windows Vista一起引入的,而微软管理控制台文档的等效版本似乎是前者的基础。

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

这个程序以两种方式计算,都基于这里和这里的信息。第一种是使用TEXTMETRICS结构的tmAveCharWidth域;第二个使用第一个链接中的GetTextExtentPoint32()函数。然后,它重复这个过程,考虑到古代系统字体(见第一个链接)。

在Windows 7中使用

运行此程序
  • BUTTON_SIZE_X保持在50(列出的几个东西的宽度)
  • BUTTON_SIZE_Y更改为25(仅vista和up命令链接的一行文本的列出高度)

使得我们基于布局页面的预期尺寸为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

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

第二个程序只是创建一个虚拟对话框,并调用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版通用控件库时,他们决定包括用于确定控件适当大小的消息!…只有部分控件:

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

现在如何比较Windows中的控件?嗯,在Windows XP上看起来确实是正确的,但是Windows 7的对话框和其他控件令人惊讶地不一致(有些仍然使用Tahoma甚至MS Sans Serif作为对话框字体!),我永远无法确定什么按钮大小是正确的。

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

  • 五种计算方法中哪一种是正确的,如果布局页面上的示例不是正确的?
  • 是否有比不完整的布局和MMC布局页面更权威的关于控制大小(以及理想的节奏)的参考?
  • 在Vista之前是否有这样的参考文献可以提供线索?
  • 或者这一切都是无望的,我必须选择一些在我看来是错误的东西,无论如何?

只是一些提示:

1。获取windows控件的首选大小:

如果打开了视觉样式,则使用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控件布局

最新更新