14

该软件基于 Delphi 7 构建。

在我的 XP 机器上,表单按我的预期调整大小。但是,在两台 Vista 机器上,我的组件的锚点设置为 [akLeft, akTop, akRight, akBottom],但是当我调整表单大小时,组件不会随着表单拉伸,在右侧和底部边缘留下空白. 在 XP 机器上,组件正确地与表单一起拉伸。

因此,Vista 机器似乎忽略了锚属性。任何想法是什么导致了这个以及如何解决它?

重要更新 (François):
我们的D2007应用程序和所有 x64 窗口都有同样的问题。
安德烈亚斯的回答确实是解决办法。所以它与 D7 或 Vista 无关。

4

6 回答 6

12

如果您的控件有很多父控件,则可能与“Windows 内核堆栈溢出”问题有关。如果你在 64 位系统上运行它,内核堆栈溢出发生得更快。(更多关于这里: http: //news.jrsoftware.org/news/toolbar2000/msg07779.html

在 Embarcadero 的 CodeCentral 上是这个错误的解决方法(它也几乎 1:1 复制到 Delphi 2009 VCL 中):http ://cc.embarcadero.com/Item/25646

于 2009-08-31T10:41:32.290 回答
2

这可能是因为 Vista 显示的透明框架。(为了让不同的窗口具有相同的透明外观。

尝试使用“对齐”(alClient)而不是锚点。由于您正在使用所有锚点,因此更有意义。

于 2009-08-31T03:14:01.227 回答
2

在 Delphi 4 中引入锚点之前,我们动态调整组件的大小以达到相同的效果。您可以轻松移动/调整表单onresize事件中的组件。

通过缓冲方法,将表单的doublebuffered属性设置为true可以减少闪烁。paint我记得我们过去也必须自己实现!

于 2009-08-31T09:49:09.870 回答
1

作为我建议的动态调整大小的替代方案,根据 Hemant 的建议,我将一些工作代码(如下)放在一起。只需创建一个 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.
于 2009-08-31T22:14:28.333 回答
0

尝试在 Vista 上以 XP 兼容模式运行该程序。Delphi 7 编译的程序可能不完全支持 Vista 本地模式(这并不奇怪,真的)。

于 2009-08-31T02:55:51.490 回答
0

看起来这是一个很老的问题,无论如何,这是宇宙中唯一一个解决这个问题的方法:使用老式的 Windows 编程调整大小方法,使用 API 捕获 WM_SIZE 和 WM_SIZING,这是可靠的方法,并且可以在你知道的每个 Windows 中运行.

当然,这意味着您必须主要使用 GetClientRect() 来确定宽度和高度,然后根据这些值调整控件的大小,这听起来像是试图点燃宇宙飞船,但这是最好的。

否则,您可以在调整大小的过程中做一些更实际和快速的事情,例如:

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;

希望能帮助别人!

干杯!

于 2010-05-21T20:09:55.467 回答