Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi TRegistry typsicherer machen (https://www.delphipraxis.net/138110-tregistry-typsicherer-machen.html)

blackdrake 3. Aug 2009 21:07


TRegistry typsicherer machen
 
Delphi-Quellcode:
unit Registry2;

{

  Registry2.pas von Daniel Marschall, Version: 2009-08-03
  (C) 2009 ViaThinkSoft.

  Erweiterung der TRegistry, TRegIniFile und TRegistryIniFile, die die
  Typsicherheit durch Zuhilfenahme der Aufzählungstypen THKEY und TRegAccess
  verbessert. Dies kann auch Vorteilhaft sein, wenn diese Werte im
  Objektinspektor aufgelistet werden sollen.

  Das Problem bei TRegistry: Der Typ HKEY ist vom Typ Cardinal und kann daher
  nicht mit einem TIdentMapEntry erfasst werden. Daher können in VCLs die
  HKEYs nicht aufgelistet werden. Diese Ableitung behebt das Problem.

  Anmerkung: Bei den Aufzählungstypen wurde kein "Unknown" Wert miteinbezogen.
  Sollte ein unerwarteter Fall eintreten (z.B. neue Version der Windows.pas)
  wird eine Exception ausgelöst.

  Enthaltene Klassen

  TRegistry2:      Überschreibt alle HKEYs
  TRegistry3:      Überschreibt alle HKEYs und alle Registry-Access*
  TRegIniFile:     Überschreibt alle Registry-Access*
  TRegistryIniFile: Überschreibt alle Registry-Access*

  * Dies kann unter Umständen nicht erwünscht sein, da es sich nur auf die
    grundlegenden Typen ALL, READ, WRITE und EXECUTE beschränkt.
    (EXECUTE wird per Compilerschalter nicht mitberechnet, wenn READ mit
    dem selben Wert definiert ist, so wie es bei Delphi 7 der Fall ist)

  Kleines Manko bei TRegistry3: Das Symbol TRegistry3.Create(AAccess: LongWord)
  ist weiterhin sichtbar. Dieses Symbol sollte daher nicht aufgerufen werden,
  da hier Werte eingegeben werden können, die weder KEY_ALL_ACCESS,
  KEY_READ/KEY_EXECUTE noch KEY_WRITE sind und deswege bei TRegistry3.GetAccess
  eine EUnknownRegistryCase-Exception auslösen würde.

}

interface

uses
  SysUtils, Classes, Registry, Windows;

{$IF KEY_READ <> KEY_EXECUTE}
  {$DEFINE ADD_CASE_EXECUTE} // Derzeit ist dies der Fall
{$IFEND}

type
  // siehe Windows.pas: HKEY_*
  // Alle verfügbaren
  THKEY = (hkClassesRoot, hkCurrentUser, hkLocalMachine,
    hkUsers, hkPerformanceData, hkCurrentConfig, hkDynData);

  // siehe Windows.pas: KEY_*
  // Eine grobe Auswahl der wichtigen Elemente
  TRegAccess = (raAll, raRead, raWrite
    {$IFDEF ADD_CASE_EXECUTE}, raExecute{$ENDIF});

  EUnknownRegistryCase = class(Exception);

  TRegistry2 = class(TRegistry)
  private
    function GetRootKey: THKEY;
    procedure SetRootKey(Value: THKEY);
    function GetCurrentKey: THKEY;
  protected
    procedure ChangeKey(Value: THKEY; const Path: string);
    function GetBaseKey(Relative: Boolean): THKEY;
    function GetKey(const Key: string): THKEY;
    procedure SetCurrentKey(Value: THKEY);
  published
    property CurrentKey: THKEY
      read GetCurrentKey;
    property RootKey: THKEY
      read GetRootKey write SetRootKey { default hkCurrentUser };
  end;

  TRegistry3 = class(TRegistry2)
  private
    function GetAccess: TRegAccess;
    procedure SetAccess(Value: TRegAccess);
  public
    constructor Create(AAccess: TRegAccess); overload;
  published
    property Access: TRegAccess
      read GetAccess write SetAccess;
  end;

  TRegIniFile2 = class(TRegIniFile)
  public
    constructor Create(const FileName: string; AAccess: TRegAccess); overload;
  end;

  TRegistryIniFile2 = class(TRegistryIniFile)
  public
    constructor Create(const FileName: string; AAccess: TRegAccess); overload;
  end;

implementation

type
  KEY = LongWord;

resourcestring
  LNG_UNKNOWN_CASE = 'Registry2.pas: An unknown %s value was found.';

function HKEY2ENUM(AHKEY: HKEY): THKEY;
begin
  case AHKEY of
    HKEY_CLASSES_ROOT: result := hkClassesRoot;
    HKEY_CURRENT_USER: result := hkCurrentUser;
    HKEY_LOCAL_MACHINE: result := hkLocalMachine;
    HKEY_USERS: result := hkUsers;
    HKEY_PERFORMANCE_DATA: result := hkPerformanceData;
    HKEY_CURRENT_CONFIG: result := hkCurrentConfig;
    HKEY_DYN_DATA: result := hkDynData;
  else
    raise EUnknownRegistryCase.CreateResFmt(@LNG_UNKNOWN_CASE, ['HKEY']);
  end;
end;

function REGACCESS2ENUM(AAccess: KEY): TRegAccess;
begin
  case AAccess of
    KEY_ALL_ACCESS: result := raAll;
    KEY_READ: result := raRead;
    KEY_WRITE: result := raWrite;
    {$IFDEF ADD_CASE_EXECUTE}KEY_EXECUTE: result := raExecute;{$ENDIF}
  else
    raise EUnknownRegistryCase.CreateResFmt(@LNG_UNKNOWN_CASE, ['ACCESS']);
  end;
end;

function ENUM2HKEY(AHKEY: THKEY): HKEY;
begin
  result := HKEY_CURRENT_USER; // Verhindert Compilermeldung

  case AHKEY of
    hkClassesRoot: result := HKEY_CLASSES_ROOT;
    hkCurrentUser: result := HKEY_CURRENT_USER;
    hkLocalMachine: result := HKEY_LOCAL_MACHINE;
    hkUsers: result := HKEY_USERS;
    hkPerformanceData: result := HKEY_PERFORMANCE_DATA;
    hkCurrentConfig: result := HKEY_CURRENT_CONFIG;
    hkDynData: result := HKEY_DYN_DATA;
  end;
end;

function ENUM2REGACCESS(AAccess: TRegAccess): KEY;
begin
  result := KEY_ALL_ACCESS; // Verhindert Compilermeldung

  case AAccess of
    raAll: result := KEY_ALL_ACCESS;
    raRead: result := KEY_READ;
    raWrite: result := KEY_WRITE;
    {$IFDEF ADD_CASE_EXECUTE}raExecute: result := KEY_EXECUTE;{$ENDIF}
  end;
end;

{ TRegistry2 }

function TRegistry2.GetRootKey: THKEY;
begin
  result := HKEY2ENUM(inherited RootKey);
end;

procedure TRegistry2.SetRootKey(Value: THKEY);
begin
  inherited RootKey := ENUM2HKEY(Value);
end;

procedure TRegistry2.ChangeKey(Value: THKEY; const Path: string);
begin
  inherited ChangeKey(ENUM2HKEY(Value), Path);
end;

function TRegistry2.GetBaseKey(Relative: Boolean): THKEY;
begin
  result := HKEY2ENUM(inherited GetBaseKey(Relative));
end;

function TRegistry2.GetKey(const Key: string): THKEY;
begin
  result := HKEY2ENUM(inherited GetKey(Key));
end;

procedure TRegistry2.SetCurrentKey(Value: THKEY);
begin
  inherited SetCurrentKey(ENUM2HKEY(Value));
end;

function TRegistry2.GetCurrentKey: THKEY;
begin
  result := HKEY2ENUM(inherited CurrentKey);
end;

{ TRegistry3 }

constructor TRegistry3.Create(AAccess: TRegAccess);
begin
  inherited Create(ENUM2REGACCESS(AAccess));
end;

procedure TRegistry3.SetAccess(Value: TRegAccess);
begin
  inherited Access := ENUM2REGACCESS(Value);
end;

function TRegistry3.GetAccess: TRegAccess;
begin
  result := REGACCESS2ENUM(inherited Access);
end;

{ TRegIniFile2 }

constructor TRegIniFile2.Create(const FileName: string; AAccess: TRegAccess);
begin
  inherited Create(FileName, ENUM2REGACCESS(AAccess));
end;

{ TRegistryIniFile2 }

constructor TRegistryIniFile2.Create(const FileName: string;
  AAccess: TRegAccess);
begin
  inherited Create(FileName, ENUM2REGACCESS(AAccess));
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz