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;

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

Ура!