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;
надежда помогает кому-то еще!
Ура!