Delphi 7 формы, якоря не работают в Vista

программа на Делфи 7.

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

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

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

6 ответов


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

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


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

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


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

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


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

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


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

конечно, это означает, что вы должны использовать в основном 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 ;

Я делаю такого рода кодирование и функции только во всех окнах независимо от того, какая версия это будет.

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

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;

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

Ура!