我正在使用Delphi的GetPropValue()函数来获取某些类型对象的某些属性的值TControl.一切正常,当我得到简单的属性值,例如Value,Opacity等等,但我使用firemonkey有一些扩展属性,比如RotationCenter,它有RotationCenter.X和RotationCenter.Y,甚至是在文本的特性 TextSettings,这些特性与子类型我无法获得价值.
在这个例子中,我正确地得到了值:
If IsPublishedProp (Component_cc, 'Value') then
EditValue.Text: = GetPropValue (Component_cc, 'Value', true);
Run Code Online (Sandbox Code Playgroud)
哪里Component_cc:TControl; 并且是动态创建的,它也可以是任何类型的Firemonkey组件(到目前为止一切正常,一切正常).
当我需要使用下面的表格时,它不起作用.
If IsPublishedProp (Component_cc, 'RotationCenter.X') then
EditRotationCenterX.Text: = GetPropValue (CC_component, 'RotationCenter.X', true);
Run Code Online (Sandbox Code Playgroud)
有没有人知道通过这个功能扩展这些属性的方法?
首先,CC_component的RotationCenter属性实际上是一个TPosition降序的类的实例TPersistent.
其次,调用时不能使用点分表示法IsPublishedProp.
您可以使用GetObjectProp先检索内部TPosition实例,然后X从那里访问该属性:
(假设一个简单的FMX应用程序,其中一个表单包含一个TButton被调用的Button1和一个TEdit被调用的EditRotationCenterX.)
procedure TForm1.Button1Click(Sender: TObject);
var
CC_component : TComponent;
CC_component_RotationCenter : TPosition;
begin
CC_component := Button1;
if IsPublishedProp(CC_component, 'RotationCenter') then
begin
CC_component_RotationCenter := TPosition(GetObjectProp(CC_component, 'RotationCenter'));
EditRotationCenterX.Text := CC_component_RotationCenter.X.ToString;
end
end;
Run Code Online (Sandbox Code Playgroud)
更新,对于Set类型的属性:
对于Set type属性,您需要使用以检索其序数值GetOrdProp.这将是表示当前值中包含哪些元素的位数组.然后,您只需测试是否设置了适当的位.这是我更喜欢的方法.
或者,您可以使用GetSetProp它将返回Set的当前值中元素的文本表示.例如,如果Set的值为[TCorner.BottonLeft, TCorner.TopRight],您将返回字符串值"TopRight,BottonLeft".然后,检查目标元素的名称是否出现在返回的字符串中的任何位置.如果Delphi RTL或FMX库将来发生变化,则此方法很容易失败.
(这个例子从上面添加一个TRectangle名为Rectangle1和一个TCheckBox调用的形状cbCornerBottonRight到简单的FMX App :)
procedure TForm1.Button1Click(Sender: TObject);
var
CC_component : TComponent;
CC_component_Corners : nativeint;
CC_component_CornersAsString : string;
begin
CC_component := Rectangle1;
if IsPublishedProp(CC_component, 'Corners') then
begin
// Using this method will make your code less sensitive to
// changes in the ordinal values of the Set's members or
// changes to names of the enumeration elements.
//
CC_component_Corners := GetOrdProp(CC_component,'Corners');
cbCornerBottonRight.IsChecked := ((1 shl ord(TCorner.BottomRight)) and CC_component_Corners) <> 0;
// This approach may break if the names of the elements of
// the TCorner enumeration are ever changed. (BTW, they have
// been in the past: "cvTopLeft", "cvTopRight", "cvBottomLeft",
// and "cvBottomRight" are now deprecated)
//
CC_component_CornersAsString := GetSetProp(CC_component,'Corners');
cbCornerBottonRight.IsChecked := CC_component_CornersAsString.IndexOf('BottomRight') >= 0;
end;
end;
Run Code Online (Sandbox Code Playgroud)
在谈到旧RTTI时,您可以这样做.你需要深入了解结构.索要X属性TPosition对象:
var
O: TObject;
X: Integer;
begin
if PropIsType(Component_cc, 'RotationCenter', tkClass) then
begin
O := GetObjectProp(Component_cc, 'RotationCenter');
if Assigned(O) and PropIsType(O, 'X', tkInteger) then
X := GetOrdProp(O, 'X');
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |