Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Как читать REG_MULTI_SZ значение?

01.01.2007
uses
  Registry;

procedure ReadREG_MULTI_SZ(const CurrentKey: HKey; const Subkey, ValueName: string;
  Strings: TStrings);
var
  valueType: DWORD;
  valueLen: DWORD;
  p, buffer: PChar;
  key: HKEY;
begin
  // Clear TStrings
  Strings.Clear;
  // open the specified key
  if RegOpenKeyEx(CurrentKey,
                  PChar(Subkey),
                  0, KEY_READ, key) = ERROR_SUCCESS then
  begin
    // retrieve the type and data for a specified value name
    SetLastError(RegQueryValueEx(key,
                 PChar(ValueName),
                 nil,
                 @valueType,
                 nil,
                 @valueLen));
    if GetLastError = ERROR_SUCCESS then
      if valueType = REG_MULTI_SZ then
      begin
        GetMem(buffer, valueLen);
        try
          // receive the value's data (in an array).
          RegQueryValueEx(key,
                          PChar(ValueName),
                          nil,
                          nil,
                          PBYTE(buffer),
                          @valueLen);
          // Add values to stringlist
          p := buffer;
          while p^ <> #0 do
          begin
            Strings.Add(p);
            Inc(p, lstrlen(p) + 1)
          end
        finally
          FreeMem(buffer)
        end
      end
      else
        raise ERegistryException.Create('Stringlist expected/ String Liste erwartet...')
    else
      raise ERegistryException.Create('Cannot Read MULTI_SZ Value/'+
        'Kann den MULTI_SZ Wert nicht lesen...');
  end;
end;

// Test it:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ReadREG_MULTI_SZ(HKEY_CURRENT_USER, 'Software\XYZ', 'Test44', Memo1.Lines);
end;

{******************************************}
{2. by Ralph Friedman }
 
{
 Question:
 I want to read out the binary-value "problems" of the path
 HKEY_DYN_DATA\Config Manager\Enum\[add the key of a hardware component] to
 detect if a hardware component is troubled and not working right.
 But I cannot handle the ReadBinaryData-Method of TRegistry correct.
 Everytime I use it, it always returns "4" as content of the buffer.
 How do I detect if the content of the binary-key "problems" is
 not "00 00 00 00" but something else like "16 00 00 00" or such?
}
 
{Answer: Here's an example of ReadBinaryData }
 
 
procedure TFrmReadBinary.Button1Click(Sender: TObject);
const
  CKeyName: string = 'System\Setup';
  CValName: string = 'NetcardDlls';
var
  keyGood: boolean;
  p: integer;
  regKey: TRegistry;
  tmpStr: string;
  vSize: integer;
begin
  regKey := TRegistry.Create;
  try
    regKey.RootKey := HKEY_LOCAL_MACHINE;
    keyGood  := regKey.OpenKey(CKeyName, False);
 
    if (keyGood) then
    begin
      vSize := regKey.GetDataSize(CValName);
 
      if (vSize > 0) then
      begin
        SetLength(tmpStr, vSize);
        regKey.ReadBinaryData(CValName, tmpstr[1], vSize);
 
        repeat
          p := Pos(#0, tmpStr);
 
          if p <> 0 then
          begin
            Delete(tmpStr, p, 1);
            Insert(#13#10, tmpStr, p);
          end;
        until p = 0;
 
        (*StringReplace(tmpStr, #0, #13#10, [rfReplaceAll]); *)
 
        ListBox1.Items.Text := tmpStr;
      end;
    end;
  finally
    regKey.Free;
  end;
end;

{******************************************}
{3. by Michael Winter }
 
procedure RaiseWin32Error(Code: Cardinal);
var
  Error: EWin32Error;
begin
  Error := EWin32Error.CreateResFmt(@SWin32Error, [Code,
    SysErrorMessage(Code)]);
  Error.ErrorCode := Code;
  raise Error;
end;
 
// Write REG_MULTI_SZ
procedure TForm1.Button1Click(Sender: TObject);
const
  Str = 'multiple'#0'strings'#0'in one'#0'registry'#0'value'#0;
var
  Reg: TRegistry;
  Res: Integer;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if not Reg.OpenKey('\Software\Test\RegMultiSzTest', true) then
      raise Exception.Create('Can''t open key');
    Res := RegSetValueEx(
      Reg.CurrentKey,     // handle of key to set value for
      'TestValue',        // address of value to set
      0,                  // reserved
      REG_MULTI_SZ,       // flag for value type
      PChar(Str),         // address of value data
      Length(Str) + 1);   // size of value data
    if Res <> ERROR_SUCCESS then
      RaiseWin32Error(Res);
  finally
    Reg.Free;
  end;
end;
 
// Read REG_MULTI_SZ
procedure TForm1.Button2Click(Sender: TObject);
var
  Reg: TRegistry;
  DataType: Cardinal;
  DataSize: Cardinal;
  Res: Integer;
  Str: String;
  i: Integer;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if not Reg.OpenKeyReadOnly('\Software\Test\RegMultiSzTest') then
      raise Exception.Create('Can''t open key');
    DataSize := 0;
    Res := RegQueryValueEx(
      Reg.CurrentKey,     // handle of key to query
      'TestValue',        // address of name of value to query
      nil,                // reserved
      @DataType,          // address of buffer for value type
      nil,                // address of data buffer
      @DataSize);         // address of data buffer size
    if Res <> ERROR_SUCCESS then
      RaiseWin32Error(Res);
    if DataType <> REG_MULTI_SZ then
      raise Exception.Create('Wrong data type');
    SetLength(Str, DataSize - 1);
    if DataSize > 1 then begin
      Res := RegQueryValueEx(
        Reg.CurrentKey,     // handle of key to query
        'TestValue',        // address of name of value to query
        nil,                // reserved
        @DataType,          // address of buffer for value type
        PByte(Str),         // address of data buffer
        @DataSize);         // address of data buffer size
      if Res <> ERROR_SUCCESS then
        RaiseWin32Error(Res);
    end;
 
    for i := Length(Str) downto 1 do
      if Str[i] = #0 then
        Str[i] := #13;
    ShowMessage(Str);
  finally
    Reg.Free;
  end;
end;

Взято с сайта https://www.swissdelphicenter.ch/en/tipsindex.php

type

 
  TExRegistry = class(TRegistry)
  public
    function ReadStrings(const ValueName: String): String;
  end;
 
function TExRegistry.ReadStrings(const ValueName: String): String;
var
  ValueType : DWORD;
  ValueLen  : DWORD;
  P, Buffer : PChar;
begin
  Result := '';
  SetLastError(RegQueryValueEx(CurrentKey, PChar (ValueName), nil,
    @ValueType, nil, @ValueLen));
  if GetLastError = ERROR_SUCCESS then
  begin
    if ValueType = REG_MULTI_SZ then
    begin
      GetMem(Buffer, ValueLen);
      try
        RegQueryValueEx(CurrentKey, PChar(ValueName), nil, nil, PBYTE(Buffer), @ValueLen);
        P := Buffer;
        while P^ <> #0 do
        begin
          if Result <> '' then 
            Result := Result + sLineBreak;
          Result := Result + P;
          Inc(P, lstrlen(P) + 1);
        end;
      finally
        FreeMem (Buffer);
      end;
    end
    else
      raise ERegistryException.Create ('String list expected');
  end
  else
    raise Exception.Create ('Unable read MULTI_SZ value');
end;

 

Автор: Александр (Rouse_) Багель

Взято из https://forum.sources.ru