Delphi 将子组件属性类型转换为ini文件
我现在很头疼组件属性的类型转换 在我的表格上,我有一个叫做“场景”的TPanel。同样在表单上,我有一个按钮创建一个Delphi 将子组件属性类型转换为ini文件,delphi,delphi-xe2,firemonkey,Delphi,Delphi Xe2,Firemonkey,我现在很头疼组件属性的类型转换 在我的表格上,我有一个叫做“场景”的TPanel。同样在表单上,我有一个按钮创建一个t选择,在该t选择中创建一个t图像,然后将图片加载到该图像中。TSelection的名称通过称为“ImgObjName”的TEdit分配。然后,它将该名称写入一个文件。t选择的事件分配给代码中的其他程序。正如您所知,TSelection组件可以在运行时四处移动(并调整大小)。TImage的HitTest已关闭,而TSelection已打开 上面的工作,因为我希望它,但下一部分是我卡
t选择
,在该t选择
中创建一个t图像
,然后将图片加载到该图像中。TSelection的名称通过称为“ImgObjName”的TEdit分配。然后,它将该名称写入一个文件。t选择的事件分配给代码中的其他程序。正如您所知,TSelection组件可以在运行时四处移动(并调整大小)。TImage的HitTest已关闭,而TSelection已打开
上面的工作,因为我希望它,但下一部分是我卡住了。基本上,在计时器上,我想将每个子组件的一些选定属性写入TMemIniFile。有两种方法我愿意这样做1) 写入每个子项的属性以分离tMeminifile。
2) 将每个子级的属性写入一个TMemIniFile,但使
部分
标识该部分中的值与哪个组件相关
我尝试了几种不同的方法,但它们都给我带来了一些重大问题(通常是“索引超出范围”)
我目前的方法就是这样
ChgPos
是一个全局布尔变量,当其中一个TSelection对象上的mousedown事件被激发时为TRUE,当MouseUp事件被激发时为FALSE。这个布尔过程非常适合这些目的,因此不需要进行任何更改
TimerBar
是在设计时创建的TTrackBar
。它的值根据计时器而变化
AnimIni
是在代码前面分配的TMemIniFile。为此,我将其设置为不释放文件(以便不存在访问冲突)
我正在努力想办法解决这个问题。我得到了“索引超出范围”的错误。我还需要保存TImage组件属性(特别是父组件和位图位置,但我觉得让代码至少与一个组件一起工作对我来说很重要)
我对类型转换有点陌生(因为我以前的所有项目都是在不需要它的情况下工作的),但到目前为止,我在这方面的所有经验都非常成功。只是在这个特殊的案例中,它被证明变得比我在没有帮助的情况下所能解决的更复杂
我确实尝试过WriteComponent
和ReadComponent
并使用多个文件来实时传输与TimerBar值相关的数据,但对于我想要实现的目标来说,速度太慢了(特别是在写函数上)。inifile方法确实可以在我之前的测试中使用,但它实际上是在运行时创建的多个组件的类型转换中使用的,我对此有问题
有人能告诉我一个可能的解决方案或者我应该朝哪个方向走吗?你的循环计数器和索引属性不匹配<代码>组件计数和
组件[]
一起进行。和ChildrenCount
和ChildrenCount[]
一起。您希望使用后一对,因为您对控件的子级很感兴趣。ComponentCount
和Components[]
属性是指所有权,这是一个不同的概念
更重要的是,循环结束,但在循环变量之后继续使用循环变量。这显然是错误的。它看起来需要在循环内部和场景内部。Children[i]是t选择
测试
作为旁白,
ChildrenCount
与ComponentCount
和ControlCount
一起在语法上不正确。此属性应命名为ChildCount
循环计数器和索引属性不匹配<代码>组件计数和组件[]
一起进行。和ChildrenCount
和ChildrenCount[]
一起。您希望使用后一对,因为您对控件的子级很感兴趣。ComponentCount
和Components[]
属性是指所有权,这是一个不同的概念
更重要的是,循环结束,但在循环变量之后继续使用循环变量。这显然是错误的。它看起来需要在循环内部和场景内部。Children[i]是t选择
测试
作为旁白,ChildrenCount
与ComponentCount
和ControlCount
一起在语法上不正确。此属性应命名为ChildCount
组件
属性上使用该索引,而是在子级
属性上使用该索引。(我假设您的代码已编译且XE2具有Children
属性,否则我认为您的意思是控件
和控件计数
)i
。我肯定你想把它放在里面。编译器还警告您:
FOR循环变量“i”在循环后可能未定义
始终确保你有零!编译器错误、警告和提示ChgPos
为false时,才需要从MemIniFile加载设置AnimIni.ReadInteger
函数、PosX
和PosY
的默认值,但它们都是未赋值的。如果ini文件中没有节
var
i: Integer;
PosX, PosY: Integer;
begin
for i := 0 to Scene.ChildrenCount - 1 do
begin
if Scene.Components[i] is TSelection then
begin
PosX := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosX', PosX);
PosY := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosY', PosY);
end;
end;
if ChgPos = False then
begin
if Scene.Components[i] is TSelection then
begin
(Scene.Components[i] as TSelection).Position.X := PosX;
(Scene.Components[i] as TSelection).Position.Y := PosY;
end;
end
else if ChgPos = True then
begin
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosX', Round((Scene.Children[i] as TSelection).Position.X));
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosY', Round((Scene.Children[i] as TSelection).Position.Y));
end;
end;
var
i: Integer;
Selection: TSelection;
PosX, PosY: Integer;
begin
for i := 0 to Scene.ChildrenCount - 1 do
if Scene.Children[i] is TSelection then
begin
Selection := Scene.Children[i] as TSelection;
if ChgPos then
begin
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosX', Round(Selection.Position.X));
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosY', Round(Selection.Position.Y));
end
else
begin
PosX := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) +
'_Object' + IntToStr(i), 'PosX', PosX);
PosY := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) +
'_Object' + IntToStr(i), 'PosY', PosY);
Selection.Position.X := PosX;
Selection.Position.Y := PosY;
end;
end;
end;