Первое, что я попробовал, не сработало: я догадался, что проблема связана с более широкими границами окна в Vista. Я полагал, что UpdateAnchorRules в VCL каким-то образом неправильно вычислялись из-за разницы между шириной дизайна и фактической шириной окна в Vista. Глядя на источник VCL, стало ясно, что изменение якорей приведет к повторному вызову UpdateAnchorRules и (надеюсь) к правильному вычислению, поскольку теперь у него есть фактическая ширина формы.
Я добавил
TAnchors t = BlahBtn->Anchors;
t >> akRight;
BlahBtn->Anchors = t;
t << akRight;
BlahBtn->Anchors = t;
конструктору моей формы.
Нет радости. Поведение было совершенно незатронутым.
Я подумал, что это может быть слишком рано, поэтому перенес тот же код в метод FormShow, но безуспешно. В качестве последней попытки я изменил дизайн формы, чтобы больше не иметь akRight для кнопки, и изменил код на
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 в «классическом» виде).
Надеюсь, это кому-нибудь поможет.