Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чтение из реестра REG_MULTI_SZ [D6, D7]


solenko ©   (2005-09-05 22:31:00) 

Здравствуйте!
Можноли с помощью TRegistry прочитать из реестра значение типа REG_MULTI_SZ? Если да то как?
Если нет, то как работать с результатом, полученным ит функции API, какой разделитель используется для разграничения строк, а какой определяет конец параметра?

Заранее благодарен.


Lamer@fools.ua   (2005-09-07 08:16:00) [1]

>> Джо ©   (05.09.05 22:41) [2]

1. Если первая строка пустая, то код сработает неправильно.
2.
> for I := 0 to Sz do

Sz?

3. Я понимаю, что это пример. Но вот это очень плохо (перераспределение памяти):
else
    S := S + Ch;


В этом плане код в [3] лучше.


Турист   (2005-09-07 07:09:00) [2]

>Джо ©   (07.09.05 02:16) [7]
Вы дали свой ответ, я свой, в чем проблема ?


Джо   (2005-09-07 02:16:00) [3]


> [6] Турист   (06.09.05 07:15)
> >Турист   (05.09.05 23:28) [3]
> Поправка

Поправка "не в кассу". Требовалось прочитать, а не записать. Что, уж не обессудьте, было и решено в [2].


Турист   (2005-09-06 07:15:00) [4]

>Турист   (05.09.05 23:28) [3]
Поправка


procedure TMyRegistry.WriteStrings(const aValueName: string; aStrings: TStrings);
var
 sMultiString: string;
begin
 sMultiString := StringReplace(aStrings.Text, #13#10, #0, [rfReplaceAll]);
 if RegSetValueEx(CurrentKey, PChar(aValueName), 0, REG_MULTI_SZ, PChar(sMultiString),
    Length(sMultiString) + 1) <> ERROR_SUCCESS then
   raise ERegistryException.CreateResFmt(@SRegSetDataFailed, [aValueName])
end;


Турист   (2005-09-05 23:33:00) [5]

>Джо ©   (05.09.05 23:31) [4]
Возможно, но работает, вроде, правильно


Джо   (2005-09-05 23:31:00) [6]


>  [3] Турист   (05.09.05 23:28)

Весьма громоздко, коллега :)


Турист   (2005-09-05 23:28:00) [7]

>solenko ©   (05.09.05 22:31)  



uses
 Registry, RtlConsts;

type
 TMyRegistry = class(TRegistry)
   procedure ReadStrings(const aValueName: string; aStrings: TStrings);
   procedure WriteStrings(const aValueName: string; aStrings: TStrings);
 end;

procedure TMyRegistry.WriteStrings(const aValueName: string; aStrings: TStrings);
var
 sMultiString: string;
begin
 sMultiString := StringReplace(aStrings.Text, #13#10, #0, [rfReplaceAll]);
 if RegSetValueEx(CurrentKey, PChar(aValueName), 0, REG_MULTI_SZ, PChar(sMultiString),
   Length(sMultiString)) <> ERROR_SUCCESS then
   raise ERegistryException.CreateResFmt(@SRegSetDataFailed, [aValueName])
end;

procedure TMyRegistry.ReadStrings(const aValueName: string; aStrings: TStrings);
var
 dwDataSize, dwDataType: Integer;
 P: PChar;  
 sMultiString: string;
begin
 aStrings.BeginUpdate;
 try
   aStrings.Clear;
   if (RegQueryValueEx(CurrentKey, PChar(aValueName), nil,
                       @dwDataType, nil, @dwDataSize) = ERROR_SUCCESS) and
      (dwDataType = REG_MULTI_SZ) and (dwDataSize > 0) then begin
     SetLength(sMultiString, dwDataSize);
     if (RegQueryValueEx(CurrentKey, PChar(aValueName), nil, @dwDataType, PByte(sMultiString),
                        @dwDataSize) = ERROR_SUCCESS) and (dwDataType = REG_MULTI_SZ) then begin
       P := PChar(sMultiString);
       while P^ <> #0 do begin
         aStrings.Add(P);
         P := StrEnd(P) + 1
       end
     end
   end
 finally
   aStrings.EndUpdate
 end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 with TMyRegistry.Create do try
   if OpenKey('Software\Test', True) then begin
     WriteStrings('Test', ListBox1.Items);
     ReadStrings('Test', ListBox2.Items);
   end
 finally
   Free
 end
end;


Джо   (2005-09-05 22:41:00) [8]

Ну, можно написать такого наследника.


 TRegistryEx = class (TRegistry)
 private
 public
   procedure ReadLines (const KeyName: string; AStrings: TStrings);
 end;
implementation

procedure TRegistryEx.ReadLines(const KeyName: string; AStrings: TStrings);
var
 Buff: array of Char;
 I, Sz: Cardinal;
 Ch,PrevCh: Char;
 S: string;
begin
 AStrings.Clear;
 Sz := GetDataSize(KeyName);
 SetLength (Buff,Sz);
 ReadBinaryData(KeyName,Buff[0],Sz);
 // parse data
 PrevCh := #0;
 S := '';
 for I := 0 to Sz do
 begin
   Ch := Buff[I];
   if (Ch=#0) and (PrevCh=#0) then
      Break;
   if (Ch=#0) then
   begin
     AStrings.Add(S);
     S := '';
   end
   else
     S := S + Ch;
   PrevCh := Ch;
 end
end;


Джо   (2005-09-05 22:35:00) [9]

По пунктам.
1. TRegistry.ReadBinaryData
2. REG_MULTI_SZ
Array of null-terminated strings that are terminated by two null characters.


Наверх

Титульная страница Поиск, карта сайта Написать письмо