delphitype-kinds

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


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?


Solution

  • 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;