Delphi 7 форм, якоря, не работающие в Vista
Программное обеспечение построено на Delphi 7.
На моей машине XP форма изменяется, как я ожидаю. Однако на двух машинах Vista у меня есть компоненты с привязками, установленными на [akLeft, akTop, akRight, akBottom], но когда я изменяю размер формы, компоненты не растягиваются с формой, оставляя пробелы справа и внизу, На машине XP компоненты правильно растягиваются с помощью формы.
Итак, похоже, что машина Vista игнорирует свойство anchor. Любые идеи, что вызывает это и как его исправить?
Важное обновление (François):
У нас была та же проблема с нашим D2007 приложением и на всех окнах x64.
Ответ Андреаса действительно был залогом.
Так что это не D7, а Vista.
Ответы
Ответ 1
Возможно, это связано с проблемой Windows ", которая возникает, если у вашего управления много родителей. И если вы запустите его на 64-битной системе, переполнение стека ядра происходит намного быстрее. (подробнее об этом здесь: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)
В Embarcadero CodeCentral - это обходной путь для этой ошибки (который также скопирован почти в 1:1 в Delphi 2009 VCL): http://cc.embarcadero.com/Item/25646
Ответ 2
Возможно, это связано с прозрачным фреймом, который демонстрирует Vista. (Чтобы придать различным окнам такой же прозрачный вид.
Попробуйте использовать "Align" (alClient) вместо привязок. Поскольку вы используете все якоря, это имеет смысл.
Ответ 3
Прежде чем анкеры были внедрены в Delphi 4, мы динамически изменяли компоненты, чтобы добиться такого же эффекта. Вы можете легко перемещать/настраивать компоненты в форме onresize
.
Установка свойства doublebuffered
формы true
может уменьшить мерцание, путем буферизации метода paint
. Я помню, что нам тоже приходилось это реализовывать!
Ответ 4
В качестве альтернативы динамическому изменению размеров, предложенному мной на основе предложения Хеманта, я применил несколько рабочих кодов (ниже). Просто создайте приложение форм VCL, перейдите на tpanel
, который не касается какого-либо края формы (по умолчанию, Align = alNone
) и замените Unit1 на код ниже. Когда вы запустите его, вы увидите 4 желтые панели, окружающие первоначально добавленную, а центральная панель изменит размер с помощью формы (как будто все якоря были true
).
unit Unit1;
interface
uses
Windows, Classes, Controls, Forms, ExtCtrls, Graphics;
type
TPanelPos = (ppLeft, ppRight, ppTop, ppBottom);
TForm1 = class(TForm)
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
Panels : array[TPanelPos] of tpanel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
PanelPos : TPanelPos;
begin
for PanelPos := ppLeft to ppBottom do
begin
Panels[PanelPos] := tpanel.Create(Form1);
Panels[PanelPos].Parent := Form1;
Panels[PanelPos].Color := clYellow;
case PanelPos of
ppLeft :
begin
Panels[PanelPos].Align := alLeft;
Panels[PanelPos].Width := Panel1.Left - 1;
end;
ppRight :
begin
Panels[PanelPos].Align := alRight;
Panels[PanelPos].Width := Form1.Width - Panel1.Left - Panel1.Width;
end;
ppTop :
begin
Panels[PanelPos].Align := alTop;
Panels[PanelPos].Height := Panel1.Top - 1;
end;
ppBottom :
begin
Panels[PanelPos].Align := alBottom;
Panels[PanelPos].Height := Form1.Height - Panel1.Top - Panel1.Height;
end;
end;
Panel1.Align := alClient;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
PanelPos : TPanelPos;
begin
for PanelPos := ppLeft to ppBottom do
Panels[PanelPos].Free;
end;
end.
Ответ 5
Попробуйте запустить программу в режиме совместимости с XP в Vista. Программы, составленные Delphi 7, могут не полностью поддерживать собственный режим Vista (неудивительно, что это действительно так).
Ответ 6
Похоже, это довольно старый вопрос, так или иначе, единственное решение этой проблемы во Вселенной: используйте старый метод прорисовки в стиле Windows, используя API, который захватывает WM_SIZE и WM_SIZING, что он является невероятным и будет функционировать в каждой Windows. Знаю.
Конечно, это означает, что вы должны использовать главным образом GetClientRect() для определения witdhs и высот, а затем изменять размеры элементов управления на основе таких значений, которые могут звучать как попытка воспламенения космического корабля, но это лучше всего.
В противном случае вы можете сделать что-то более практичное и быстрое в процедуре изменения размера, например:
Control1.Left := Control2.Left + (buttonControl.Width div 2) - (buttonControl3.Width div 2);
//for example widths
Control4.Width := (Control.Width * 4) + (Control.Left * 8) + 54 ;
Я делаю такие кодировки и функции только для всех Windows, независимо от того, какая версия была бы.
Вам понадобятся только некоторые значения в разрешении экрана для справки:
iCXSCREEN := GetSystemMetrics(SM_CXSCREEN);
iCYSCREEN := GetSystemMetrics(SM_CYSCREEN);
if ((iCXSCREEN = 1280) and (iCYSCREEN = 720)) or ((iCXSCREEN = 1280) and (iCYSCREEN = 700)) or ((iCXSCREEN = 1280) and (iCYSCREEN = 600)) then begin
// blah blah
end;
Надежда помогает кому-то еще!
Ура!