windows Delphi 7 形式,锚点在 Vista 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1355258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Delphi 7 forms, anchors not working in Vista
提问by Robo
The software is built on Delphi 7.
该软件基于 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.
在我的 XP 机器上,表单按我的预期调整大小。但是,在两台 Vista 机器上,我的组件的锚点设置为 [akLeft, akTop, akRight, akBottom],但是当我调整表单大小时,这些组件不会随表单一起拉伸,在右侧和底部边缘留下空白. 在 XP 机器上,组件正确地随着表单拉伸。
So, it seems like the Vista machine is ignoring the anchor property. Any ideas what's causing this and how to fix it?
因此,Vista 机器似乎忽略了锚点属性。任何想法是什么导致了这个以及如何解决它?
Important update (Fran?ois):
We had the same problem with our D2007application and on all x64 windows.
Andreas' answer was indeed the fix.
So it is not D7 nor Vista related.
重要更新 (Fran?ois):
我们的D2007应用程序和所有 x64 窗口都遇到了同样的问题。
安德烈亚斯的回答确实是解决办法。所以它与 D7 或 Vista 无关。
采纳答案by Andreas Hausladen
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)
也许这与如果您的控件有许多父控件时出现的“Windows 内核堆栈溢出”问题有关。如果您在 64 位系统上运行它,内核堆栈溢出发生得更快。(更多关于这里: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
在 Embarcadero 的 CodeCentral 上是此错误的解决方法(它也几乎以 1:1 的比例复制到 Delphi 2009 VCL 中):http: //cc.embarcadero.com/Item/25646
回答by Hemant
It might be because of the transparent frame which is shown by Vista. (In order to give different windows same transparent appearance.
可能是因为Vista显示的透明框架。(为了给不同的窗口相同的透明外观。
Try using "Align" (alClient) instead of anchors. Since you are using all anchors, that makes more sense.
尝试使用“Align”(alClient)而不是锚点。由于您正在使用所有锚点,这更有意义。
回答by Argalatyr
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.
在 Delphi 4 中引入锚点之前,我们动态调整组件的大小以达到相同的效果。您可以轻松地移动/调整表单onresize
事件中的组件。
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!
通过缓冲方法,将表单的doublebuffered
属性设置为true
可以减少闪烁paint
。我记得我们过去也必须自己实施!
回答by Argalatyr
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
).
作为我建议的动态调整大小的替代方案,根据 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.
回答by Neuron
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.
看起来这是一个很老的问题,无论如何这是宇宙中这个问题的唯一一个解决方案:使用使用 API 捕获 WM_SIZE 和 WM_SIZING 的旧式 Windows 编程大小调整方法,这是可靠的方法,将在您知道的每个 Windows 中运行.
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.
当然,这意味着您必须主要使用 GetClientRect() 来确定宽度和高度,然后根据这些值调整控件的大小,当然这听起来像是试图点燃宇宙飞船,但这是最好的。
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.
无论是哪个版本,我都会在所有 Windows 中执行这种编码和功能。
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!
干杯!
回答by Argalatyr
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).
尝试在 Vista 上以 XP 兼容模式运行该程序。Delphi 7 编译的程序可能不完全支持 Vista 本机模式(这并不奇怪,真的)。