问题
The software is built on Delphi 7.
On my XP machine, the form resizes as I expect. However, on two Vista machines, I have components with anchors set to [akLeft, akTop, akRight, akBottom], but when I resize the form, the components don't stretch with the form, leaving blank spaces on the right and bottom edge. On the XP machine, the components correctly stretch with the form.
So, it seems like the Vista machine is ignoring the anchor property. Any ideas what's causing this and how to fix it?
Important update (François):
We had the same problem with our D2007 application and on all x64 windows.
Andreas' answer was indeed the fix.
So it is not D7 nor Vista related.
回答1:
Maybe it is related to the "Windows Kernel stack overflow" problem that occurs if your control has many parents. And if you run it on a 64 bit system the kernel stack overflow happens much faster. (more about this here: http://news.jrsoftware.org/news/toolbar2000/msg07779.html)
On Embarcadero's CodeCentral is a workaround for this bug (which is also copied almost 1:1 into the Delphi 2009 VCL): http://cc.embarcadero.com/Item/25646
回答2:
It might be because of the transparent frame which is shown by Vista. (In order to give different windows same transparent appearance.
Try using "Align" (alClient) instead of anchors. Since you are using all anchors, that makes more sense.
回答3:
Before anchors were introduced in Delphi 4, we resized components dynamically to achieve the same effect. You can easily move/adjust the components in the form's onresize
event.
Setting the form's doublebuffered
property to true
may reduce flicker, by buffering the paint
method. I recall we used to have to implement that ourselves, too!
回答4:
As an alternative to the dynamic resizing I suggested, based on Hemant's suggestion I slapped together some working code (below). Just create a VCL forms application, drop on a tpanel
that does not touch any edge of the form (by default, Align = alNone
) and replace Unit1 with the code below. When you run it, you'll see 4 yellow panels surrounding the one initially added, and the central panel will resize with the form (as if all anchors were 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:
Try running the program in XP compatibility mode on Vista. Programs compiled by Delphi 7 may not fully support Vista native mode (no surprise there, really).
回答6:
It looks this is pretty old question, anyway here's the only one solution for this problem in the Universe : Use the old style Windows programming sizing method using API trapping WM_SIZE and WM_SIZING, that's the infalible one and will function in every Windows you'll know.
Of course this means you have to use mainly GetClientRect() to determine witdhs and heights and then resize controls based on such values, sure that may sound like trying to ignite a spaceship but it's the best.
Otherwise you could do something more practical and quickly in a resizing procedure like :
Control1.Left := Control2.Left + (buttonControl.Width div 2) - (buttonControl3.Width div 2);
//for example widths
Control4.Width := (Control.Width * 4) + (Control.Left * 8) + 54 ;
I do that kind of coding and functions in just all Windows no matter wich version it would be.
You only need some values on the screen resolution for reference doing something like this :
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;
Hope helps someone else!
Cheers!
来源:https://stackoverflow.com/questions/1355258/delphi-7-forms-anchors-not-working-in-vista