|
REG_MULTI_SZ 에서 각 항목의 분리는 #0 으로 하며, 맨 끝은 #0, #0 으로 끝납니다.
아래 소스는 줄줄히 읽어서 TStrings 객체에 집어 넣는 델파이 예제 입니다.
procedure TExRegistry.ReadStrings(const valueName: string; strings: TStrings);
var
valueType : DWORD;
valueLen : DWORD;
p, buffer : PChar;
begin
strings.Clear;
SetLastError (RegQueryValueEx (CurrentKey, PChar (valueName), Nil, @valueType, Nil, @valueLen));
if GetLastError = ERROR_SUCCESS then
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
strings.Add (p);
Inc (p, lstrlen (p) + 1)
end
finally
FreeMem (buffer)
end
end
else
raise ERegistryException.Create ('String list expected')
else
raise EExRegistryException.CreateLastError (
'Unable read MULTI_SZ value')
end;
procedure TExRegistry.WriteStrings(const valueName: string; strings: TStrings);
var
p, buffer : PChar;
i : Integer;
size : DWORD;
begin
size := 0;
for i := 0 to strings.Count - 1 do
Inc (size, Length (strings [i]) + 1);
Inc (size);
GetMem (buffer, size);
try
p := buffer;
for i := 0 to strings.count - 1 do
begin
lstrcpy (p, PChar (strings [i]));
Inc (p, lstrlen (p) + 1)
end;
p^ := #0;
SetLastError (RegSetValueEx (CurrentKey, PChar (valueName), 0, REG_MULTI_SZ, buffer, size));
if GetLastError <> ERROR_SUCCESS then
raise EExRegistryException.CreateLastError (
'Unable to write MULTI_SZ value');
finally
FreeMem (buffer)
end
end;
ps. EExRegistryException is just this...
EExRegistryException = class (ERegistryException)
private
fCode: Integer;
function GetError : string;
public
constructor CreateLastError (const st : string);
constructor Create (code : DWORD; const st : string);
property Code : Integer read fCode;
end;
...
constructor EExRegistryException.Create(code: DWORD; const st:
string);
begin
fCode := code;
inherited Create (GetError + ':' + st);
end;
constructor EExRegistryException.CreateLastError(const st: string);
begin
fCode := GetLastError;
inherited Create (GetError + ':' + st);
end;
function EExRegistryException.GetError: string;
var
msg : string;
function GetErrorMessage (code : Integer) : string;
var
hErrLib : THandle;
msg : PChar;
flags : Integer;
function MAKELANGID (p, s : word) : Integer;
begin
result := (s shl 10) or p
end;
begin
hErrLib := LoadLibraryEx ('netmsg.dll', 0, LOAD_LIBRARY_AS_DATAFILE);
try
flags := FORMAT_MESSAGE_ALLOCATE_BUFFER or
FORMAT_MESSAGE_IGNORE_INSERTS or
FORMAT_MESSAGE_FROM_SYSTEM;
if hErrLib <> 0 then
flags := flags or FORMAT_MESSAGE_FROM_HMODULE;
if FormatMessage (flags, pointer (hErrLib), code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
PChar (@msg), 0, Nil) <> 0 then
try
result := msg;
finally
LocalFree (Integer (msg));
end
finally
if hErrLib <> 0 then
FreeLibrary (hErrLib)
end
end;
begin
msg := GetErrorMessage (fCode);
if msg = '' then
result := Format ('Error %d', [fCode])
else
result := Format ('Error %d : %s', [fCode, msg])
end;
강창수 님이 쓰신 글 :
: 어떻게 하나요?
:
: 빌더5에서 제공하는 TRegistry->GetDataType으로 조사해보니 rdUnknown으로 나오더군요.
:
: 'reg_multi_sz'이라는 것이 두개의 널 문자열로 끝나는 문자열이라는데,
:
: TRegistry->ReadString으로는 안읽히는군요.
:
: IpAddress, Gateway SubnetMask같은 것들이 'reg_multi_sz' 형식으로 저장되는데(win2k에서)
:
: 어떻게 읽어야 할까요?
:
: 현재는 Win32Api로 시도해볼려고 하는데, 빌더5에서 제공하는 다른 방법이 있는지 궁금합니다.
:
: 그럼 답변 기다리겠습니다......
|