Delphi 7 формы, якоря не работают в Vista - PullRequest
14 голосов
/ 31 августа 2009

Программное обеспечение построено на Delphi 7.

На моем компьютере с XP размер формы изменяется, как я и ожидал. Однако на двух машинах Vista у меня есть компоненты с привязками, установленными на [akLeft, akTop, akRight, akBottom], но когда я изменяю размер формы, компоненты не растягиваются с формой, оставляя пустые места на правом и нижнем крае , На машине XP компоненты правильно растягиваются с формой.

Итак, похоже, что машина Vista игнорирует свойство привязки. Любые идеи, что вызывает это и как это исправить?

Важное обновление (Франсуа):
У нас была та же проблема с нашим D2007 приложением и на всех x64 окнах .
Ответ Андреаса был действительно исправлением. Так что это не связано ни с D7, ни с Vista.

Ответы [ 6 ]

12 голосов
/ 31 августа 2009

Возможно, это связано с проблемой «переполнения стека ядра Windows», которая возникает, если у вашего элемента управления много родителей. И если вы запускаете его в 64-битной системе, переполнение стека ядра происходит намного быстрее. (подробнее об этом здесь: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)

В Embarcadero CodeCentral - обходной путь для этой ошибки (которая также копируется почти 1: 1 в VCL Delphi 2009): http://cc.embarcadero.com/Item/25646

2 голосов
/ 31 августа 2009

До того, как якоря были введены в Delphi 4, мы динамически изменяли размеры компонентов для достижения того же эффекта. Вы можете легко перемещать / настраивать компоненты в событии onresize формы.

Установка свойства doublebuffered формы на true может уменьшить мерцание, буферизуя метод paint. Я помню, что раньше мы сами это тоже реализовывали!

2 голосов
/ 31 августа 2009

Это может быть из-за прозрачной рамки, которую показывает Vista. (Для того, чтобы разные окна выглядели одинаково прозрачно.

Попробуйте использовать «Align» (alClient) вместо якорей. Поскольку вы используете все якоря, это имеет больше смысла.

1 голос
/ 01 сентября 2009

В качестве альтернативы предложенному мной динамическому изменению размеров, основываясь на предложении Хеманта, я собрал некоторый рабочий код (ниже). Просто создайте приложение форм 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.
0 голосов
/ 22 мая 2010

Похоже, это довольно старый вопрос, в любом случае, вот единственное решение этой проблемы во Вселенной: используйте метод определения размеров Windows в старом стиле, используя API-интерфейсы WM_SIZE и WM_SIZING, это непогрешимый и будет работать в каждой Windows узнаю.

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

В противном случае вы можете сделать что-то более практичное и быстрое в процедуре изменения размера, например:

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;

Надежда помогает кому-то еще!

Ура!

0 голосов
/ 31 августа 2009

Попробуйте запустить программу в режиме совместимости с XP на Vista. Программы, скомпилированные с помощью Delphi 7, могут не полностью поддерживать собственный режим Vista (в этом нет ничего удивительного).

...