FMX关于TControl.EnumControls枚举控件并将枚举结果进行排序及枚举属性赋值
一、原理
uses FMX.Controls;
TControl = class(TFmxObject, IControl, IContainerObject, IAlignRoot, IRotatedControl, IAlignableObject,
IEffectContainer, IGestureControl, ITabStopController, ITriggerAnimation, ITriggerEffect)
procedure EnumControls(const Proc: TFunc<TControl, TEnumControlsResult>); overload;
function EnumControls(Proc: TEnumControlsRef; const VisibleOnly: Boolean = True): Boolean; overload;
deprecated 'Use another version of EnumControls';
二、代码案例
procedure TfmxMergeImageAndWords.btnMergeImgsClick(Sender: TObject);
var LTBitmap:TBitmap; LQuality:PBitmapCodecSaveParams;
LDstTRectF,LScrTRectF:TRectF;
LWidthTImageTo,LHeightTImageTo:Integer;
LFindImgList:TList<TImage>;
LImgStrList:TStringList;
LResult:string;
//procedure EnumControls(const Proc: TFunc<TControl, TEnumControlsResult>); overload;
//function EnumControls(Proc: TEnumControlsRef; const VisibleOnly: Boolean = True): Boolean; overload;
//const Proc: TFunc<TFmxObject, TEnumProcResult>
function FindMergingImg:string;
Var LImagePrior,LImageCurrt:TImage;
LBitmapPriorHeight:Single;
LImageCount:Integer;
begin
LImageCurrt:=nil; LBitmapPriorHeight:=0; LResult:='';
//LFindImgList:=TList<FMX.Objects.TImage>.Create;
LImgStrList:=TStringList.Create;
ScrollBox1.EnumControls(
procedure (const AControl: TControl; var Done: boolean)
begin
if (AControl.ClassName = 'TImage') then
begin
LImageCurrt:=TImage(AControl);
LImgStrList.AddObject(LImageCurrt.Name,LImageCurrt);
//:加入TStringList以便全部加入完毕后进行排序
end;
Done:=false;//:不要停继续找下一个
end
,true //:只枚举可见的组件
);
//LFindImgList.Sort; //:枚举类型只能按照索引号index排序
LImgStrList.Sorted:=true;
//:枚举完后按TStringList的Strings行次的名称进行排序
try
LImageCurrt:=nil;
for LImageCount:=0 to (LImgStrList.Count-1) do
begin
LImagePrior:=LImageCurrt;
LImageCurrt := TImage(LImgStrList.Objects[LImageCount]);
//剪切多大的矩形图:
LScrTRectF.Top:=0;
LScrTRectF.Left:=0;
LScrTRectF.Bottom:=
LImageCurrt.Position.Point.Y+LImageCurrt.Bitmap.Height;
LScrTRectF.Right:=
LImageCurrt.Position.Point.X+LImageCurrt.Bitmap.Width;
//在哪个目标位置矩形画图:
if LImagePrior=nil then
LBitmapPriorHeight:=LBitmapPriorHeight;
if LImagePrior<>nil then
LBitmapPriorHeight:=LBitmapPriorHeight +LImagePrior.Bitmap.Height;
LDstTRectF.Top:=LScrTRectF.Top
+LBitmapPriorHeight; //:该图上面所有合并图的高度
LDstTRectF.Left:=LImageCurrt.Position.Point.X;
LDstTRectF.Bottom:=LDstTRectF.Top +LScrTRectF.Bottom;
LDstTRectF.Right:=
LImageCurrt.Position.Point.X+LImageCurrt.Bitmap.Width;
try //开始画图:
DrawLongImage(
ImgDrawed,LImageCurrt,
LWidthTImageTo,LHeightTImageTo,LTBitmap,LScrTRectF,LDstTRectF );
finally
end;
LResult:=LResult+'枚举后排序的当前图是:'+LImageCurrt.Name+slinebreak;
end;
finally
//FreeAndNil(LFindImgList);
FreeAndNil(LImgStrList);
end;
if LImageCurrt<>nil then
Result:=LResult+'找到的最后1个排序图是:'+LImageCurrt.Name
else Result:='没图';
end;
begin
if FSavePath.Trim='' then
begin
{$IFDEF POSIX}
try
{$IFDEF Android}
//Memo1.Lines.Add(AndoidRequestPermissions('读取文件')); Memo1.Lines.Add(AndoidRequestPermissions('写入文件'));
AndoidRequestPermissions('读取文件');
AndoidRequestPermissions('写入文件');
{$ENDIF Android}
finally
SubPathOfAppPublished;
FSavePath:=GetSubPathOfAppPublished;
end;
{$ENDIF POSIX}
end;
{$IFDEF IOS}
LWidthTImageTo:=720; LHeightTImageTo:=3840;
{$ENDIF IOS} //3840:IOS最大值3张
{$IFDEF Android}
LWidthTImageTo:=720; LHeightTImageTo:=7680;
{$ENDIF Android} //7680:Android最大值6张
{$IFDEF MSWINDOWS}
LWidthTImageTo:=720; LHeightTImageTo:=28160;
{$ENDIF MSWINDOWS} //38400:Wondows最大值30张
System.TMonitor.Enter(ImgDrawed,0);
try
FindMergingImg;
//Memo1.Lines.Clear; Memo1.Lines.Add(FindMergingImg);
finally
ImgDrawed.Bitmap.SaveToFile(FSavePath+'ImgDrawed.jpg');
//:将文件保存到本地指定路径
end;
System.TMonitor.Exit(ImgDrawed);
VertScrollBox1.BringToFront; VertScrollBox1.Visible:=true;
end;
三、关于动态产生的控件在枚举后对属性赋值
1、被调用窗体:
procedure TfmxMergeImageAndWords.FormShow(Sender: TObject);
var CountComponent:Integer; ComponentName:string;
begin
ScrollBox1.BringToFront;
ComponentName:='';
//枚举设置显示方式及点击事件:fmxMergeImageAndWords.ScrollBox1
for CountComponent:=0 to ComponentCount-1 do
begin //:还是用传统的枚举,进行属性赋值吧!!!
if Components[CountComponent] is TImage then
begin
ComponentName:=TImage(Components[CountComponent]).Name;
if ComponentName.IndexOf('ImgMerging',0,10)>=0 then
begin
TImage(Components[CountComponent]).BringToFront;
TImage(Components[CountComponent]).OnClick:=fmxMergeImageAndWords.ControlAction;
end;
end;
end;
Selection1.BringToFront;
{ //FMX.Controls.EnumControls枚举不全(同步枚举,非异步):
fmxMergeImageAndWords.ScrollBox1.EnumControls(
procedure (const AControl: TControl; var Done: boolean)
begin
Done:=false;//:不要停继续找下一个
ComponentName:=AControl.Name;
if (AControl.ClassName = 'TImage') then
begin
//if (pos('ImgMerging',ComponentName)>0) then
if (ComponentName.IndexOf('ImgMerging',0,length(ComponentName))>=0) then
begin
AControl.BringToFront;
AControl.OnClick:=fmxMergeImageAndWords.ControlAction;
//ComponentName:=ComponentName+AControl.Name+SLineBreak;
Memo1.Lines.BeginUpdate;
Memo1.Lines.Add(ComponentName);
Memo1.Lines.EndUpdate;
end;
end;
end
,true //:只枚举可见的组件
);
//}
end;
2、调用者窗体某事件:
for LImageCount := 4 to 21 do
begin
try
LTImageName:=FillBeforeString(IntToStr(LImageCount),2,'0');
finally
LTImage:=TImage.Create(fmxMergeImageAndWords);
end;
try
LTImage.Bitmap.SetSize(720,1280);
//LTImage.Bitmap.LoadFromFile(FSavePath+'StreamMergeImgs.jpg');
//:样本Bitmap:ImgDrawed.Bitmap:
LTImage.Bitmap.Assign(ImgDrawed.Bitmap);
LTImage.Name:='ImgMerging'+FillBeforeString(IntToStr(LImageCount),2,'0');
LTImage.TagString:='ImgMerging'
+LTImageName;
LTImage.Width:=360; LTImage.Height:=640;
LTImage.Scale.X:=1; LTImage.Scale.Y:=1;
LTImage.WrapMode:=TImageWrapMode.Fit;
LTImage.Align:=TAlignLayout.Top;
LTImage.CanFocus:=true;
LTImage.HitTest:=true;
LTImage.Visible:=true;
// LTImage.Parent:=fmxMergeImageAndWords.ScrollBox1;
fmxMergeImageAndWords.ScrollBox1.BeginUpdate;
//fmxMergeImageAndWords.ScrollBox1.InsertComponent(LTImage);
fmxMergeImageAndWords.ScrollBox1.AddObject(LTImage);
fmxMergeImageAndWords.ScrollBox1.EndUpdate;
Memo1.Lines.Add(LTImage.Name);
finally
LTImage:=nil;
end;
end;
finally
//FreeAndNil(LTImage);
end;
fmxMergeImageAndWords.Show;