An argument that accepts any kind of Types (like: boolean, string, float.. etc)

163 views Asked by At

i have this code here:

type  // This Enumerator Type for Handling the Registry Results ...
 TRegistryKind = (rkBOOL, rkSTRING, rkEXPANDSTR, rkINTEGER, rkFLOAT, rkCURRENCY, rkBINARY_DATA, rkDATE, rkTIME, rkDATE_TIME);

 TRegistryKindResult = record
   AsBool: Boolean;
   AsString: string;
   AsInteger: Integer;
   AsFloat: Single;
   AsCurrency: Currency;
 end;

what i need here is to create a single procedure with universal pram that accept any kind of input Types and save them to registry ..
here is the trick:

procedure TAppSettings.Save_Setting_ToRegistry(AKey, AItem_Setting: String;
    AValue: **UnknownType**; ARegKind: TRegistryKind);
var
  Reg: TRegIniFile;
begin
  Reg := TRegIniFile.Create(AKey);
  try
    case ARegKind of
      rkBOOL: Reg.WriteBool('', AItem_Setting, AValue);
      rkSTRING: Reg.WriteString('', AItem_Setting, AValue);
    end;

    Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;

what should i do for the param AValue ? is there a smart way that can tell my Delphi IDE to accept any input from the 5 kinds that i defined in TRegistryKindResult record above?

4

There are 4 answers

5
Andreas Rejbrand On BEST ANSWER

The old-school approach is to use variants. Then, in fact, you don't even need the TRegistryKind parameter:

procedure SaveSetting(const AKey, ASetting: string; AValue: Variant);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey(AKey, True) then
    begin
      case VarType(AValue) of
        varSmallint, varInteger, varShortInt, varByte, varWord:
          Reg.WriteInteger(ASetting, AValue);
        varCurrency:
          Reg.WriteCurrency(ASetting, AValue);
        varSingle, varDouble:
          Reg.WriteFloat(ASetting, AValue);
        varBoolean:
          Reg.WriteBool(ASetting, AValue);
        varString, varUString:
          Reg.WriteString(ASetting, AValue);
      else
        raise Exception.Create('Unsupported variant type.');
      end;
    end;
  finally
    Reg.Free;
  end;
end;

To test it:

procedure TForm1.FormCreate(Sender: TObject);
begin
  SaveSetting('Software\Rejbrand\Test', 'intsetting', 123);
  SaveSetting('Software\Rejbrand\Test', 'cursetting', Currency(3.1415));
  SaveSetting('Software\Rejbrand\Test', 'fltsetting', Double(3.1415));
  SaveSetting('Software\Rejbrand\Test', 'boolsetting', True);
  SaveSetting('Software\Rejbrand\Test', 'strsetting', 'Hello, World!');
end;
3
Antonio Petricca On

Here is a solution (used in the past, but not tested now):

procedure TAppSettings.Save_Setting_ToRegistry(AKey, AItem_Setting: String;
    const AValue; ARegKind: TRegistryKind);
var
  Reg: TRegIniFile;
  VBool: Boolean absolute AValue;
  VString: String absolute AValue;
  VInteger: Integer absolute AValue;
  VFloat: Single absolute AValue;
  VCurrency: Currency absolute AValue;
begin
  Reg := TRegIniFile.Create(AKey);
  try
    case ARegKind of
      rkBOOL: Reg.WriteBool('', AItem_Setting, VBool);
      rkSTRING: Reg.WriteString('', AItem_Setting, VString);
      // Manage the other types...
    end;

    Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;
0
Uwe Raabe On

Unit System.RTTI provides the type TValue for that.

procedure TAppSettings.Save_Setting_ToRegistry(AKey, AItem_Setting: string; AValue: TValue; ARegKind: TRegistryKind);
var
  Reg: TRegIniFile;
begin
  Reg := TRegIniFile.Create(AKey);
  try
    case ARegKind of
      rkBOOL:
        Reg.WriteBool('', AItem_Setting, AValue.AsBoolean);
      rkSTRING:
        Reg.WriteString('', AItem_Setting, AValue.AsString);
    end;

    Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;
0
Remy Lebeau On

You can use a Variant:

procedure TAppSettings.Save_Setting_ToRegistry(AKey, AItem_Setting: String;
  AValue: Variant; ARegKind: TRegistryKind);
var
  Reg: TRegIniFile;
begin
  Reg := TRegIniFile.Create(AKey);
  try
    case ARegKind of
      rkBOOL: Reg.WriteBool('', AItem_Setting, AValue);
      rkSTRING: Reg.WriteString('', AItem_Setting, AValue);
      ...
    end;
    Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;