Forms 格式错误';Delphi中的位置计算
我遇到了一个小问题。Forms 格式错误';Delphi中的位置计算,forms,delphi,vcl,Forms,Delphi,Vcl,我遇到了一个小问题。 想象两件事:形式,应该被掩盖——掩盖形式;以及覆盖模板的模板-瓷砖。 我的主要目标是用瓷砖覆盖我的封面。所以它看起来像瓷砖。我用下图来说明这个想法 黄色为封面形式,棕色为瓷砖形式。在这张图片上,您可以看到表单彼此之间的位置太近,它们之间没有可用空间。这就是我需要的。 但当我试图达到同样的效果,我只是得到了不满意的结果。如下图所示 第二个图像在最后一个平铺后有偏移。这是因为形状的大小不同。我不知道我的封面表格的确切宽度。我只是把封面的整个宽度分成三部分。但如果封面形式有宽
想象两件事:形式,应该被掩盖——掩盖形式;以及覆盖模板的模板-瓷砖。 我的主要目标是用瓷砖覆盖我的封面。所以它看起来像瓷砖。我用下图来说明这个想法
黄色为封面形式,棕色为瓷砖形式。在这张图片上,您可以看到表单彼此之间的位置太近,它们之间没有可用空间。这就是我需要的。
但当我试图达到同样的效果,我只是得到了不满意的结果。如下图所示
第二个图像在最后一个平铺后有偏移。这是因为形状的大小不同。我不知道我的封面表格的确切宽度。我只是把封面的整个宽度分成三部分。但如果封面形式有宽度,例如173像素,我的每个瓷砖的宽度将等于173/3=57.6像素,这将是58,但58*3=174,这是坏的 下面的代码在第二幅图上运行
type
TTileArray = Array of Array of TPoint;
// This routine comes here from David's answer below and were changed by me
procedure EvenlySpacedTiles(PixelCountH, PixelCountV, TileCount: Integer; var ArrayOut: TTileArray);
var
X: Integer;
Y: Integer;
OldH: Integer;
OldV: Integer;
OldCount: Integer;
OldCount1: Integer;
TempInt: Integer;
begin
if (PixelCountH) or (PixelCountV) or(TileCount) = 0 then
Exit;
OldH := PixelCountH;
OldCount1 := TileCount;
for X:=Low(ArrayOut) to High(ArrayOut) do
begin
OldV := PixelCountV;
OldCount := TileCount;
TempInt := OldH div OldCount1;
Dec(OldH, TempInt);
Dec(OldCount1);
for Y:=Low(ArrayOut) to High(ArrayOut) do
begin
ArrayOut[X, Y] := Point(TempInt, OldV div OldCount);
Dec(OldV, ArrayOut[X, Y].Y);
Dec(OldCount);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F: TForm;
P: TForm;
Delta: Integer;
PrevLeft: Integer;
PrevTop: Integer;
X:Integer;
Y: Integer;
Arr: TTileArray;
IncLeft: Integer;
begin
Delta := 3;
F := TForm.Create(Application);
F.BorderStyle := Forms.bsNone;
F.SetBounds(0, 0, 173, 115);
F.Position := poDesktopCenter;
F.Color := $11DFEE;
F.Show;
SetLength(Arr, Delta, Delta);
EvenlySpacedTiles(F.Width, F.Height, Delta, Arr);
PrevLeft := F.Left;
PrevTop := F.Top;
IncLeft := 0;
for X:=Low(Arr) to High(Arr) do
begin
PrevTop := F.Top;
Inc(PrevLeft, IncLeft);
for Y:=Low(Arr) to High(Arr) do
begin
P := TForm.Create(Application);
P.FormStyle := fsStayOnTop;
P.BorderStyle := Forms.bsNone;
P.Color := Random($FFFFFF);//clSkyBlue;
P.Show;
P.Width := Arr[X, Y].X;
P.Height := Arr[X, Y].Y;
P.Left := PrevLeft;
P.Top := PrevTop;
P.Canvas.Rectangle(P.ClientRect);
Inc(PrevTop, Arr[X, Y].y);
IncLeft := Arr[X, Y].X;
end;
end;
end;
所以我的问题是:如何独立于封面的宽度来调整所有瓷砖的宽度(每行3块)
提前谢谢
已编辑
p.S.
我修改了上面代码的一些部分。现在,它可以完美地工作,即使是非常小和大的覆盖形式宽度-从67像素。到1237像素。
当然有办法改进这段代码,但主要目标已经实现。
我想我明天就能完成垂直瓷砖的放置,并在那里发布此部分。在很多方面,大卫的评论给了我一个如何做到这一点的想法。谢谢你,大卫 p.S.S.
我已经从对角线方向阅读了David的第一条评论,所以我更新了代码,以另一种方式工作,但结果仍然不好。您可以在下图中看到它。
第一个磁贴有57像素。宽度;第二个-59像素。;第三块瓷砖-仅31像素。
我就是不知道如何使用David评论中建议的算法正确放置瓷砖。 p.S.S.
同样没有结果。
右红线显示最后一块瓷砖的大尺寸。每个瓷砖的宽度为58像素。
大卫写道: 173/3=58。173-58=115. 115/2=58. 115-58=57. 57/1=57 我能够在现实生活中计算它,但我无法在代码中实现它。
源代码已更新 p.S.S.S.
David的程序做不到它应该做的。下面的图片说明了这一点。
第一块和第二块瓷砖之间有一个间隙,右侧有一条红线,如上图所示 p.S.S.S.S.
嗯,现在我的第一部分任务已经完成了。第二个问题是增加更多的瓷砖,但我不确定我是否真的需要它们。我很感谢你能这么做!!他花了这么多时间给我解释一些事情,我不知道该怎么对他说,只是简单地说“非常感谢”。恐怕,我只能提高他的声誉,接受他的职位作为回答。它真的很管用! 在图片上,我们可以看到我需要的结果
p.S.S.S.S.S.
我已经更新了源代码,因此它也可以垂直放置平铺。
我会使用这样一个简单的算法:
function EvenlySpacedColumns(PixelCount, ColumnCount: Integer): TArray<Integer>;
var
i: Integer;
begin
Assert(PixelCount>0);
Assert(ColumnCount>0);
SetLength(Result, ColumnCount);
for i := low(Result) to high(Result) do begin
Result[i] := PixelCount div ColumnCount;
dec(PixelCount, Result[i]);
dec(ColumnCount);
end;
end;
函数EvenlySpacedColumns(PixelCount,ColumnCount:Integer):TArray;
变量
i:整数;
开始
断言(像素计数>0);
断言(ColumnCount>0);
SetLength(结果、列数);
对于i:=低(结果)到高(结果)确实开始
结果[i]:=PixelCount div ColumnCount;
dec(像素计数,结果[i]);
dec(列计数);
结束;
结束;
这里我使用了div,它实际上使用除法,然后是截断。但如果您愿意,也可以使用
Round(PixelCount/ColumnCount)
。这有点随意,所以我个人会选择整数运算,因为如果不需要的话,应该避免浮点运算。我会使用这样一种简单的算法:
function EvenlySpacedColumns(PixelCount, ColumnCount: Integer): TArray<Integer>;
var
i: Integer;
begin
Assert(PixelCount>0);
Assert(ColumnCount>0);
SetLength(Result, ColumnCount);
for i := low(Result) to high(Result) do begin
Result[i] := PixelCount div ColumnCount;
dec(PixelCount, Result[i]);
dec(ColumnCount);
end;
end;
函数EvenlySpacedColumns(PixelCount,ColumnCount:Integer):TArray;
变量
i:整数;
开始
断言(像素计数>0);
断言(ColumnCount>0);
SetLength(结果、列数);
对于i:=低(结果)到高(结果)确实开始
结果[i]:=PixelCount div ColumnCount;
dec(像素计数,结果[i]);
dec(列计数);
结束;
结束;
这里我使用了div,它实际上使用除法,然后是截断。但如果您愿意,也可以使用
Round(PixelCount/ColumnCount)
。它有点随意,所以我个人会选择整数运算,因为如果不需要的话,应该避免使用浮点运算。173不能被3整除。因此,不能对每列使用相同的宽度。而是这样做。从Npx像素开始。除以Ncol,取整。将该值用于列0。从Npx中减去该值,然后除以Ncol-1。将该值四舍五入并用于第1列。重复此操作,直到用尽像素和列。此外,除非为了简洁起见有充分的理由遗漏,否则不会将每个磁贴实现为单独的形式。改用形状或其他更合适的东西。@DavidHeffernan,你是说下一种情况,对吗?假设我有173像素宽的封面。我知道我应该每行放置三块瓷砖,所以我除以173/3=57。这是每个瓷砖的宽度。然后我将3个瓦片乘以57,得到171。我知道171小于173,根据这个事实,我应该这样做:173-171=2。这是在第二张图像上显示的最后一块瓷砖之后的一个大小位置,所以我只是增加最后一块瓷砖的宽度,以完全适合封面形式。你觉得这个方法怎么样?@DNR,不幸的是,形状不是一个好的解决方案。不。按照我描述的方式做。不需要多个应用程序。您只需要消耗一个像素库,对于每一列