1

我花了很长时间寻找解决方案并现在找到了它,我认为这对于 Stack Overflow 来说是很好的记录。所以我的回答将在这个问题之后紧随其后。

我使用的是 Borland C++ Builder 5。这可能也适用于 Delphi 的等效版本。我在 TPanel 上有一个带有 TButton 的表单。按钮设置为 akRight,akBottom。在 XP 和以前的 Windows 上,一切都很好。在 Vista 上,使用 Aero 时,按钮出现在右侧太远 4 个像素。锚定继续正常工作。

另一个例子是一个 TComboBox 的表单,它有 akTop、akRight、akLeft。该组合在 Vista 上显得太宽了 4 个像素。

回到 Vista 上的“经典”外观使一切看起来都正确。

4

1 回答 1

4

我尝试的第一件事没有奏效:我猜这个问题与 Vista 上较宽的窗口边框有关。我认为 VCL 中的 UpdateAnchorRules 由于设计宽度与 Vista 上窗口的实际宽度之间的差异而以某种方式计算不正确。查看 VCL 源代码,很明显更改锚点会导致再次调用 UpdateAnchorRules 并(希望)正确计算,因为它现在具有可用表单的实际宽度。

我添加了

TAnchors t = BlahBtn->Anchors;
t >> akRight;
BlahBtn->Anchors = t;
t << akRight;
BlahBtn->Anchors = t;

到我的表单的构造函数。

没有喜悦。行为完全不受影响。

我认为这在此过程中可能为时过早,因此将相同的代码移至 FormShow 方法,同样不成功。作为最后一次尝试,我将表单的设计更改为按钮不再具有 akR​​ight 并将代码更改为

TAnchors t = BlahBtn->Anchors;
t << akRight;
BlahBtn->Anchors = t;

...这也失败了 - 行为完全不受影响,除了我打破了 XP 上按钮的定位,以防保存的表单大小(我从注册表中读取并应用于 FormShow 中的表单)不是默认值。

在表单生命周期的各个时间点添加了一吨的调试代码,输出表单的宽度、按钮的宽度、按钮的左侧、表单的 ClientRect 等,我发现了问题。出于某种原因(可能仍然与窗口边框相关 - 我没有设法找出确切的原因),VCL 正在打开窗口,其宽度低于应有的 4 个像素。此后不久,宽度得到了纠正,但到那时,锚定(和 UpdateAnchorRules)已经将按钮的位置固定在右侧太远 4 个像素处。

解决方法是:

void __fastcall TFooBarDlg::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    int i = GetSystemMetrics(SM_CXSIZEFRAME);
    Params.Width=Params.Width+(2*(i-4));
}

这使用 Vista 报告的不同边框大小来更正表单的初始宽度。它会在 Vista 上导致正确的行为,同时在其他 Windows 版本(以及具有“经典”外观的 Vista)上保留它。

希望这可以帮助某人。

于 2009-02-08T10:51:38.263 回答