Delphi 7 forms, anchors not working in Vista

懵懂的女人 提交于 2019-11-29 06:56:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!