How does delphi convert ModalResult properties?

我怕爱的太早我们不能终老 提交于 2019-12-22 10:01:17

问题


Hopefully this is a quick one, and "Easy if you know how"...

I'm writing some kind of Serialization/Scripting class to generate forms on the fly, I tried setting a TColor the other day and got an error clBtnFace is not a valid integer value or something like that and found that the constants used in properties are registered so that they can be converted to integer, and so I added code to fetch the converter and use it.

Now today I have a similar issue with the ModalResult property but I can't work out how the DFM deserializer handles this property? Any ideas how it converts mrOK into an integer?

Edit

There isn't much of an example to give:

PropInfo := GetPropInfo(Instance, PropertyName);
SetPropValue(Instance, PropInfo, PropertyValue);

Where in this case Instance is a TButton, PropertyName is 'ModalResult' and PropertyValue is 'mrOK'


回答1:


It doesn't need to:

const
  { Dialog Box Command IDs }
  {$EXTERNALSYM IDOK}
  IDOK = 1;          ID_OK = IDOK;

const
  mrNone     = 0;
  mrOk       = idOk;

type
  TModalResult = Low(Integer)..High(Integer);

TModalResult is in someway a subrange of Integer and mrOK is just an Integer constant.




回答2:


Don't really want to answer my own question but since no one else has....

There is no converter for ModalResults, Delphi stores the Integer representation in the DFM as VilleK says in the comment to the question. As a solution I've registered a new converter

const
  ModalResults: array[0..10] of TIdentMapEntry = (
    (Value: mrNone; Name: 'mrNone'),           
    (Value: mrOk; Name: 'mrOk'),               
    (Value: mrCancel; Name: 'mrCancel'),       
    (Value: mrAbort; Name: 'mrAbort'),         
    (Value: mrRetry; Name: 'mrRetry'),         
    (Value: mrIgnore; Name: 'mrIgnore'),       
    (Value: mrYes; Name: 'mrYes'),             
    (Value: mrNo; Name: 'mrNo'),               
    (Value: mrAll; Name: 'mrAll'),             
    (Value: mrNoToAll; Name: 'mrNoToAll'),     
    (Value: mrYesToAll; Name: 'mrYesToAll'));



function ModalResultToIdent(ModalResult: Longint; var Ident: string): Boolean;
begin
    Result := IntToIdent(ModalResult, Ident, ModalResults);
end;

function IdentToModalResult(const Ident: string; var ModalResult: Longint): Boolean;
begin
    Result := IdentToInt(Ident, ModalResult, ModalResults);
end;
initialization
    RegisterIntegerConsts(TypeInfo(TModalResult), IdentToModalResult, ModalResultToIdent);



回答3:


Both of your examples you have given are sub ranges of numeric values. As such RTTI only really knows of the underlying Integer. Other examples include TCursor, TFontCharset and TTabOrder.

If you have a type like this:

  TEnum = (exOne,exTwo,exThree);

You can use RTTI to get and set 'exOne', 'exTwo' and 'exThree' as Strings.

This can be done through these methods in TypInfo.pas

function GetEnumName(TypeInfo: PTypeInfo; Value: Integer): string;
function GetEnumValue(TypeInfo: PTypeInfo; const Name: string): Integer;

If you want to use the constants that are defined for colors or ModalResults you must build your won dictionary of constant name to value, that you could then implement into your own serialization routines.

TColor implements a static dictionary called Colors, which could be used if you only use the 52 colors that it supports.

  Colors: array[0..51] of TIdentMapEntry = (
    (Value: clBlack; Name: 'clBlack'),
    ...
    (Value: clWindowText; Name: 'clWindowText'));

You can then do the following to get the color name.

var
  ColorName : String;
begin
  // Color Value must be between 0 and 51 otherwise index out of bounds
  ColorName := Colors[ColorValue];  
end;

You then could loop through the items in the Colors Array to determine the value for a given name.



来源:https://stackoverflow.com/questions/3388014/how-does-delphi-convert-modalresult-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!