Почему мои формы Borland C ++ Builder 5 с правильными элементами управления отображаются неправильно в Vista? - PullRequest
1 голос
/ 08 февраля 2009

Потратив небольшой возраст на поиски решения и найдя его, я подумал, что было бы неплохо документировать переполнение стека. Поэтому мой ответ последует сразу после этого вопроса.

Я использовал Borland C ++ Builder 5. Это, вероятно, также относится к эквивалентной версии Delphi. У меня была форма с TButton на TPanel. Для кнопки было установлено значение akRight, akBottom. На XP и предыдущих Windows все было хорошо. В Vista с помощью Aero кнопка оказалась на 4 пикселя слишком далеко вправо. Крепление продолжало работать нормально.

Другим примером была форма с TComboBox, которая имела akTop, akRight, akLeft. На Vista комбо оказалось слишком широким на 4 пикселя.

Возвращаясь к «классическому» взгляду на Vista, все выглядело правильно.

1 Ответ

4 голосов
/ 08 февраля 2009

Первое, что я попробовал, не сработало: я догадался, что проблема связана с более широкими границами окна в 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 в «классическом» виде). ​​

Надеюсь, это кому-нибудь поможет.

...