Почему мои формы Borland C ++ Builder 5 с элементами управления, привязанными справа, неправильно отображаются в Vista?

StackOverflow https://stackoverflow.com/questions/525517

Вопрос

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

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

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

Вернувшись к "классическому" виду в Vista, все появилось правильно.

Это было полезно?

Решение

Первое, что я попробовал, не сработало:Я предположил, что проблема была связана с более широкими границами окна в Vista.Я полагал, что UpdateAnchorRules в VCL каким-то образом вычислялся неправильно из-за разницы между шириной дизайна и фактической шириной окна в Vista.Глядя на исходный код VCL, было ясно, что изменение привязок приведет к повторному вызову UpdateAnchorRules и (надеюсь) правильному вычислению, поскольку теперь доступна фактическая ширина формы.

Я добавил

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

к конструктору моей формы.

Никакой радости.На поведение это совершенно не повлияло.

Я подумал, что это может быть слишком рано в процессе, поэтому перенес тот же код в метод FormShow, столь же безуспешно.В качестве последней попытки я изменил дизайн формы, чтобы больше не иметь права доступа к кнопке, и изменил код на

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 с "классическим" внешним видом).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top