{*****************************************************************************} { } { Tnt Delphi Unicode Controls } { http://www.tntware.com/delphicontrols/unicode/ } { Version: 2.3.0 } { } { Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } { } {*****************************************************************************} unit TntRegistry; {$INCLUDE TntCompilers.inc} interface uses Registry, Windows, TntClasses; {TNT-WARN TRegistry} type TTntRegistry = class(TRegistry{TNT-ALLOW TRegistry}) private procedure WriteStringEx(dwType: DWORD; const Name, Value: WideString); public procedure GetKeyNames(Strings: TTntStrings); procedure GetValueNames(Strings: TTntStrings); function ReadString(const Name: WideString): WideString; procedure WriteString(const Name, Value: WideString); procedure WriteExpandString(const Name, Value: WideString); end; implementation uses RTLConsts, SysUtils, TntSysUtils; { TTntRegistry } procedure TTntRegistry.GetKeyNames(Strings: TTntStrings); var Len: DWORD; I: Integer; Info: TRegKeyInfo; S: WideString; begin if (not Win32PlatformIsUnicode) then inherited GetKeyNames(Strings.AnsiStrings) else begin Strings.Clear; if GetKeyInfo(Info) then begin SetLength(S, (Info.MaxSubKeyLen + 1) * 2); for I := 0 to Info.NumSubKeys - 1 do begin Len := (Info.MaxSubKeyLen + 1) * 2; if RegEnumKeyExW(CurrentKey, I, PWideChar(S), Len, nil, nil, nil, nil) = ERROR_SUCCESS then Strings.Add(PWideChar(S)); end; end; end; end; {$IFNDEF COMPILER_9_UP} // fix declaration for RegEnumValueW (lpValueName is a PWideChar) function RegEnumValueW(hKey: HKEY; dwIndex: DWORD; lpValueName: PWideChar; var lpcbValueName: DWORD; lpReserved: Pointer; lpType: PDWORD; lpData: PByte; lpcbData: PDWORD): Longint; stdcall; external advapi32 name 'RegEnumValueW'; {$ENDIF} procedure TTntRegistry.GetValueNames(Strings: TTntStrings); var Len: DWORD; I: Integer; Info: TRegKeyInfo; S: WideString; begin if (not Win32PlatformIsUnicode) then inherited GetValueNames(Strings.AnsiStrings) else begin Strings.Clear; if GetKeyInfo(Info) then begin SetLength(S, Info.MaxValueLen + 1); for I := 0 to Info.NumValues - 1 do begin Len := Info.MaxValueLen + 1; RegEnumValueW(CurrentKey, I, PWideChar(S), Len, nil, nil, nil, nil); Strings.Add(PWideChar(S)); end; end; end; end; function TTntRegistry.ReadString(const Name: WideString): WideString; var DataType: Cardinal; BufSize: Cardinal; begin if (not Win32PlatformIsUnicode) then result := inherited ReadString(Name) else begin // get length and type DataType := REG_NONE; if RegQueryValueExW(CurrentKey, PWideChar(Name), nil, @DataType, nil, @BufSize) <> ERROR_SUCCESS then Result := '' else begin // check type if not (DataType in [REG_SZ, REG_EXPAND_SZ]) then raise ERegistryException.CreateFmt(SInvalidRegType, [Name]); if BufSize = 1 then BufSize := SizeOf(WideChar); // sometimes this occurs for single character values! SetLength(Result, BufSize div SizeOf(WideChar)); if RegQueryValueExW(CurrentKey, PWideChar(Name), nil, @DataType, PByte(PWideChar(Result)), @BufSize) <> ERROR_SUCCESS then raise ERegistryException.CreateFmt(SRegGetDataFailed, [Name]); Result := PWideChar(Result); end end end; procedure TTntRegistry.WriteStringEx(dwType: DWORD; const Name, Value: WideString); begin Assert(dwType in [REG_SZ, REG_EXPAND_SZ]); if (not Win32PlatformIsUnicode) then begin if dwType = REG_SZ then inherited WriteString(Name, Value) else inherited WriteExpandString(Name, Value); end else begin if RegSetValueExW(CurrentKey, PWideChar(Name), 0, dwType, PWideChar(Value), (Length(Value) + 1) * SizeOf(WideChar)) <> ERROR_SUCCESS then raise ERegistryException.CreateFmt(SRegSetDataFailed, [Name]); end; end; procedure TTntRegistry.WriteString(const Name, Value: WideString); begin WriteStringEx(REG_SZ, Name, Value); end; procedure TTntRegistry.WriteExpandString(const Name, Value: WideString); begin WriteStringEx(REG_EXPAND_SZ, Name, Value); end; end.