为什么带有右锚定控件的 Borland C++Builder 5 表单在 Vista 上显示不正确?
我花了很短的时间寻找解决方案,现在终于找到了,我认为将其记录在 Stack Overflow 上会很好。 所以我的答案将紧随这个问题之后。
我使用的是 Borland C++ Builder 5。这可能也适用于 Delphi 的等效版本。 我有一个在 TPanel 上带有 TButton 的表单。 该按钮设置为 akRight、akBottom。 在 XP 和之前的 Windows 上,一切都很好。 在 Vista 上,使用 Aero 时,按钮出现在距右侧太远的 4 个像素处。 锚定继续正常工作。
另一个例子是带有 TComboBox 的表单,其中包含 akTop、akRight、akLeft。 该组合在 Vista 上显得太宽 4 像素。
回到 Vista 上的“经典”外观使一切都正确显示。
Having spent a small age looking for the solution and having now found it, I figured this would be good to document for Stack Overflow. So my answer will follow right after this question.
I was using Borland C++ Builder 5. This probably also applies to the equivalent version of Delphi. I had a form with a TButton on a TPanel. The button was set to akRight,akBottom. On XP and prior Windows, everything was fine. On Vista, using Aero, the button appeared 4 pixels too far to the right. The anchoring continued to work fine.
Another example was a form with a TComboBox which had akTop,akRight,akLeft. The combo appeared 4 pixels too wide on Vista.
Returning to the "classic" look on Vista made everything appear correctly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我尝试的第一件事没有成功:我猜测问题与 Vista 上较宽的窗口边框有关。 我认为由于 Vista 上窗口的设计宽度和实际宽度之间的差异,VCL 中的 UpdateAnchorRules 在某种程度上计算不正确。 查看 VCL 源代码,很明显,更改锚点将导致再次调用 UpdateAnchorRules 并(希望)正确计算,因为它现在具有可用的表单的实际宽度。
我添加
到表单的构造函数中。
没有喜悦。 行为完全不受影响。
我认为这可能为时过早,因此将相同的代码移至 FormShow 方法,同样不成功。 作为最后一次尝试,我更改了表单的设计,不再有按钮的 akRight 并将代码更改为
...这也失败了 - 行为完全不受影响,除了我打破了 XP 上按钮的定位保存的表单大小(我从注册表中读出并应用于 FormShow 中的表单)不是默认大小的情况。
添加了一吨调试代码,在表单生命周期的各个时间点输出表单的宽度、按钮的宽度、按钮的左侧、表单的 ClientRect 等,我发现了问题。 由于某种原因(大概仍然与窗口边框相关 - 我没有设法找出到底是什么原因),VCL 打开的窗口宽度比应有的宽度低 4 个像素。 此后不久,宽度就得到了纠正,但到那时,锚定(和 UpdateAnchorRules)已经将按钮的位置固定在距右侧太远的 4 个像素处。
修复方法是:
这会使用 Vista 报告的不同边框大小来更正表单的初始宽度。 它会导致 Vista 上的正确行为,同时在其他 Windows 版本(以及具有“经典”外观的 Vista)上保留它。
希望这对某人有帮助。
The first thing I tried didn't work: I guessed that the problem had to do with the wider window borders on Vista. I figured UpdateAnchorRules in VCL was somehow calculating incorrectly due to the difference between the design width and the actual width of the window on Vista. Looking at the VCL source, it was clear that changing the anchors would cause UpdateAnchorRules to be called again and (hopefully) calculate correctly, since it now had the actual width of the form available.
I added
to my form's constructor.
No joy. The behaviour was entirely unaffected.
I figured this might be too early in the process, so moved the same code to the FormShow method, equally unsuccessfully. As a last try, I changed the design of the form to no longer have akRight for the button and changed the code to
...which failed too - behaviour entirely unaffected, other than that I broke the positioning of the button on XP in the case that the saved size of the form (which I read out of the registry and apply to the form in FormShow) wasn't the default.
Having added a metric tonne of debug code outputting the width of the form, width of the button, left of the button, ClientRect of the form, etc. at various points during the form's lifetime, I found the problem. For some reason (presumably still window-border-related - I didn't manage to find out exactly what the reason was), VCL was opening the window with the width 4 pixels below what it should have been. The width got corrected shortly thereafter, but by that point, the anchoring (and UpdateAnchorRules) had already fixed the positioning of the button 4 pixels too far to the right.
The fix was:
This corrects the initial width of the form, using the differing size of the border as reported by Vista. It causes the correct behaviour on Vista while retaining it on other Windows versions (and Vista with "classic" look).
Hope this helps somebody.