Avatar billede aasuper Nybegynder
18. oktober 2000 - 12:23 Der er 33 kommentarer og
1 løsning

Binær værdi i registreringsdatabasen

Hej

Jeg skal bruge en procedure til at tilføje en binær værdi til registreringsdatabasen.

Hvis vi siger, at jeg f.eks. har værdien 001111100110011000111000, hvordan skal den så tilføjes, så den kommer til at stå på helt samme måde, når jeg kigger i registreringsdatabasen.


>>AASuper
Avatar billede pellelil Nybegynder
18. oktober 2000 - 12:28 #1
Hvordan læser du værdien \"001111100110011000111000\" ?

Hvis det er 3 bytes så kan du skrive det som en streng der er 3 bytes lang via \"WriteString\" eller også kan du bruge \"WriteBinaryData\":
<SNIP>
Stores a specifically named data value associated with the current key.

procedure WriteBinaryData(const Name: String; var Buffer; BufSize: Integer);

Description

Call WriteBinaryData to store a data value associated with the current key.

Name is a string containing the name of the data value in which to store data. If Name already exists, its current value is overwritten by WriteBinary. If Name does not exist, it is created.

Buffer is a data buffer containing the data to store in the registry. BufSize indicates the size of Buffer.

Note:    Data-value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as separate files, and those file names should be stored in the registry. Application elements such as icons, bitmaps, and executable files should be stored as separate files rather than as values in the registry.

If WriteBinaryData fails, an exception is raised, and the value is not written to the registry.
</SNIP>
Avatar billede uffe_kld Nybegynder
18. oktober 2000 - 12:34 #2
vil du tilføje strengen \"001111100110011000111000\" eller værdien
4089400? Du har 3 muligheder gemme det som en streng med 0 & 1, gemme værdien en DWORD (det jo også binært) eller bruge BINARY hvor du kan kan størrere mængder af data, hvor kan jeg ikke huske.
Avatar billede aasuper Nybegynder
18. oktober 2000 - 12:35 #3
Jeg går f.eks. ind i registreringsdatabasen og vælger en vilkårlig binær værdi. Den vil jeg så tilføje under en anden nøgle, så den bliver helt magen til.

Jeg har prøvet med:

type
  TRegVaerdi = record
      Value : ShortString;
  end;

og så

RegVaerdi.Value:=\'001111100110011000111000\';
Reg.WriteBinaryData(nøgle,regvaerdi,3);



Der skal bare stå det samme inde i registreringsdatabasen. Det gør der ikke, når jeg bruger ovenstående metode.

>>AASuper
Avatar billede aasuper Nybegynder
18. oktober 2000 - 12:36 #4
-Og det SKAL være som en binær nøgle derinde.

>>AASuper
Avatar billede picard Nybegynder
18. oktober 2000 - 12:38 #5
prøv at kaste et blik på denne side, jeg tror den kan hjælpe dig :)

http://www.geocities.com/SiliconValley/Lakes/1636/registry.htm
Avatar billede pellelil Nybegynder
18. oktober 2000 - 13:15 #6
Hvad kalder du binær ? 

RegVaerdi.Value:=\'001111100110011000111000\';

Ovenstående er en streng hvor værdierne tilfældigvis er ASCII 0\'er og ASCII 1\'er det har principielt ikke noget med \"binær værdier\" at gøre. Hvis du i stedet vil regne ovenstående 0\'er og 1\'er som binære værdier så får du 3 tegn.

szStr := #62+#102+#56;  eller  szStr := \'>f8\';

Avatar billede aasuper Nybegynder
18. oktober 2000 - 13:19 #7
Tak for de hurtige svar.

Picard>> Jeg vil lige teste din løsning. Jeg vender tilbage i løbet af eftermiddagen.


>>AASuper
Avatar billede aasuper Nybegynder
18. oktober 2000 - 13:21 #8
Pellelil>> Det er ikke det, der er problemet. DER SKAL BARE STÅ \'001111100110011000111000\' INDE I REGISTRERINGSDATABASEN!


>>AASuper
Avatar billede borrisholt Novice
18. oktober 2000 - 14:12 #9
Jammen så prøv det her for at kopiere dit password til et andet sted i registerings database.

var
  Data : Array of Byte;    // Dynamic Array - Delphi4 Only !!
  sz  : Word;

procedure TForm1.Button1Click(Sender: TObject);
const
  Key  : String = \'Software\\Microsoft\\Internet Account Manager\\Accounts\\00000001\';
  Val  : String = \'POP3 Password2\';
begin
  with TRegistry.Create do
  try
    OpenKey(Key, False);
    if GetDataType(Val) = rdBinary  then
    begin
      sz := GetDataSize(Val);
      if sz > 0 then
      begin
        SetLength(Data, sz);
        ReadBinaryData(Val, Data[0], sz);
      end;
    end;
  finally
    free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  Key  : String = \'Software\\Hest\';
  Val  : String = \'POP3 Password2\';
begin
  with TRegistry.Create do
  try
    OpenKey(Key, True);
    WriteBinaryData(Val, Data[0], sz);
    CloseKey;
  finally
    Free;
  end;
end;

Jens B
Avatar billede picard Nybegynder
18. oktober 2000 - 14:14 #10
BorrisHolst >> hmmm minder utrolig meget om det kode jeg henviste til ;)

Christian
Avatar billede borrisholt Novice
18. oktober 2000 - 14:22 #11
Borrisholt, picard ikke Holst ....

Det er i væsenlige grad også tager der fra .... Men som den opmærksomme læser også allerede har bemærket så har jeg været i gang med problemer i et tidligere spm.

Hvis man så får vist en smartere metode end dem man allerede kender ... så ville det være dumt ikke at benytte den  ....

Det oprinde lige spørgsmål gik på hvordan man kopiere en binær værdi i registeringsdatabasen....


Jens B
Avatar billede pellelil Nybegynder
18. oktober 2000 - 14:27 #12
Lige inden TeleDK skodede min Internetforbindelse ville jeg havde sagt: Jeg samler lige mine to svar:
<SNIP>
var
  acData : Array[0..2] of byte;
begin
  acData[0] := 62;
  acData[1] := 102;
  acData[2] := 56;
  RegBlaBla.WriteBinaryData(\'Nøgle\', acData, 3);
end;
</SNIP>

Avatar billede borrisholt Novice
18. oktober 2000 - 14:31 #13
pellelil  > Ikke den slags ord her inde ! Man må da ikke sige TDK og min internetforbindelse i SAMME sætning !

Jens B
Avatar billede pellelil Nybegynder
18. oktober 2000 - 14:33 #14
Her betaler man en halv til en helv arm for en 2 MBit forbindelse og så dør den bedst som man er ved at poste et svar. Jeg klippede det over i en notepad så jeg ikke skulle skrive det igen da der endelig kom forbindelse igen.

Det er lige godt grov  ;-)
Avatar billede aasuper Nybegynder
18. oktober 2000 - 15:09 #15
Borrisholt>> Jeg har kun Delphi 3, så det kan ikke bruges. Jeg får først version 4 i næste måned, når alt om data bringer fuld version af Delphi 4 med bladet.



Den anden kode ser ud til at virke, der er bare et MEN: Når jeg aflæser en værdi i registreringsdatabasen, f.eks. 38(HEX) / 00111000(BIN), er det jo ikke i DEC. Dvs. at hvis jeg vil have 38 i reg.db. skal de først koverteres til Decimaltal, hvor det giver 56. Hvis jeg så sætter 56 ind i jeres forslag, giver det de 38.

Denne omregningsproces skal ikke ske manuelt, så hvordan kan man regne HEX-værdien i reg.db. om til BYTE-værdien i Delphi-koden?


>>AASuper



Avatar billede pellelil Nybegynder
18. oktober 2000 - 15:21 #16
Der sker ingen konvertering hverken den ene eller den anden vej. Det hele er et sprøgsmål om hvordan du vælger at læse værdien. Du kan ikke sige at regisrerings database har værdien $38(HEX) det er lige så rigtigt at sige at den har værdien %00111000(BIN) eller #56(DEC). RegEdit vælger bare at vise den som HEX.

Det store spørgsmål er \"Hvad vil du\" og \"hvad kender du\". Hvis du ved at du vil skrive værdien $38 så kan du vælge at skrive: acData[2] := $38;


 
Avatar billede borrisholt Novice
18. oktober 2000 - 15:22 #17
prøv at erstatte

SetLength(Data, sz);
Getmem(Data,sz);

Jens B
Avatar billede aasuper Nybegynder
18. oktober 2000 - 16:13 #18
ENDELIG virker det, når jeg bruger $ foran:


Her er proceduren:
------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
var
  B : array [0..19] of Byte;
  I : Byte;
  R: TRegistry;
  str: string;
Const
SubKey  : String = \'Software\\Hest\';

begin
R := TRegistry.Create;
str:=\'0102380036004400310038003600320030000000\';

  with R do begin
    for i:=0 to 19 do begin
    B[I]:=StrToInt(\'$\'+str[I+I+1]+str[I+2+I]);
    end;
  OpenKey(SubKey + \'\\tester\', True);
  WriteBinaryData(\'Value\', B, SizeOf(B));
  Free;
  end;
end;
-----------------------------------------------


MEN hvis nu jeg vil tage STR fra en tekstfil, og den ikke altid har samme længde, er der så nogen løsning at hente, når Delphi3 ikke kan bruge dynamisk array?



>>AASuper
Avatar billede borrisholt Novice
18. oktober 2000 - 16:59 #19
jammen du læser bare længden på din streng. ganse almindeligt med Length()

fx :

procedure TForm1.Button3Click(Sender: TObject);
var
    i,j  : Integer;
    str,tmp : String;
    buf : array of Byte;

Const
  SubKey  : String = \'Software\\Hest\';
begin
  str:=\'0102380036004400310038003600320\'; //(læst fra en fil)
  i:= Length(str);
  Getmem(buf, i);
  for j:= 0 to i div 2 do
  begin
    tmp := \'$\'+str[j+j+1]+str[j+2+j];
    buf[j] := StrToInt(tmp);
  end;

  with TRegistry.Create do
  try
    OpenKey(SubKey + \'\\tester\', True);
    WriteBinaryData(\'Value\', Buf, SizeOf(Buf));
  finally
    closekey;
    free;
  end;

  freemem(Buf);
end;


Jens B
Avatar billede aasuper Nybegynder
18. oktober 2000 - 17:28 #20
Du definerer \"BUF\" som \"Array of byte\". Den er en dynamisk tabel.

Delphi3, som jeg bruger, kan ikke bruge dynamiske arrays, som \"BUF\" nu engang er.

Dynamiske arrays understøttes først i Delphi4.


>>AASuper
Avatar billede borrisholt Novice
18. oktober 2000 - 17:32 #21
har du prøvet ?
Avatar billede borrisholt Novice
18. oktober 2000 - 17:35 #22
Ellers så brug
      buf : PByteArray;
Den var der ogsp under Delphi 3 ellers kan den implementeres som følger :

type
  PByteArray = ^TByteArray;
  TByteArray = array[0..32767] of Byte;

jens B
Avatar billede aasuper Nybegynder
18. oktober 2000 - 17:59 #23
Den virker heller ikke.
Når den skal tilføje TMP til BUF[J], opstår der en EConvertError ved \'$\'.


>>AASuper
Avatar billede borrisholt Novice
18. oktober 2000 - 18:02 #24
med præcis den kode jeg har anvist ?
Avatar billede aasuper Nybegynder
18. oktober 2000 - 18:03 #25
Ja!
Avatar billede borrisholt Novice
18. oktober 2000 - 18:04 #26
har du prøver at single steppe dig igennem det for at se hvad det går galt ... ?
jens b
Avatar billede aasuper Nybegynder
18. oktober 2000 - 18:06 #27
Jeg prøvede med en anden værdi - så virkede det.

MEN det står ikke rigtigt inde i registreringsdatabasen........
Avatar billede borrisholt Novice
18. oktober 2000 - 18:10 #28
nej det er klart du har r et byte array som bliver gemt som HEX

Jens B
Avatar billede aasuper Nybegynder
18. oktober 2000 - 18:11 #29
Jamen så kan løsningen vel ikke bruges.
Avatar billede borrisholt Novice
18. oktober 2000 - 18:15 #30
Lad mig lige tænke over det til i morgen nu vil jeg hjem (fra arbejde)

Jens B
Avatar billede aasuper Nybegynder
18. oktober 2000 - 18:16 #31
Okay!
Min løsning virkede ellers, og det er da også et bytearray!

>>AASuper
Avatar billede picard Nybegynder
18. oktober 2000 - 19:50 #32
Borrisholt >> beklager, det var ikke ment som en grovhed, blot en munter kommentar :)

Christian
Avatar billede borrisholt Novice
20. oktober 2000 - 13:06 #33
Med hiv og sving og med hjælp fra Pelle (pellelil)  er jeg kommer frem til den følgende løsning :

type
  CharSet = set of char;
Const
  SubKey  : String = \'Software\\Hest\\tester\';
  Val  : String = \'randomValue\';

Function  StripButCharSet(Const szStr : String; ChSet : CharSet) : String;
var
  iLen : Integer;
  iIdx : Integer;
begin
  Result := \'\';
  iLen := Length(szStr);
  if iLen > 0 then
    for iIdx := 1 to iLen do
      if (szStr[iIdx] in ChSet) then
        Result := Result + szStr[iIdx];
end;

Function  Hex2Int(szHex : String) : Integer;
Const
  acHexTable : Array[0..15] of char = \'0123456789ABCDEF\';
var
  iIdx : Integer;
begin
  Result := 0;
  szHex := StripButCharSet(AnsiUpperCase(szHex), [\'0\'..\'9\',\'A\'..\'F\']);
  for iIdx := 1 to Length(szHex) do begin
    Result := Result or (Pos(szHex[iIdx], acHexTable)-1);
    if iIdx < Length(szHex) then Result := Result shl 4;
  end;
end;


Function StrToBin(s : String) : Boolean;
var
  i,j : Integer;
  qq : array[0..1023] of byte;
  Reg : TRegistry;
begin
  Result := false;
  try
    s:= StripButCharSet(s,[\'0\' .. \'9\', \'A\' .. \'F\']);

    if length(s) mod 2 <> 0 then
      s:= \'0\' + s;

    j := Length(s) div 2;

    for i:= 0 to j do
      qq[i] := Hex2Int(s[i+i+1]+s[i+i+2]);

    Reg := TRegistry.Create;
    try
      Reg.RootKey := HKEY_CURRENT_USER;
      Reg.OpenKey(SubKey, true);
      Reg.WriteBinaryData(Val, qq, (Length(s) div 2));
    finally
      Reg.CloseKey;
      Reg.free;
    end;
  except
    exit;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  StrToBin(\'00 06 05 03 09 00 06 06 02 05 09 02 04 00 09 00\');
end;


Jens B

Avatar billede aasuper Nybegynder
20. oktober 2000 - 17:05 #34
Det virker, tak!

Du kan selv give nogle point til Pelle, alt efter hvor meget han har hjulpet...


>>AASuper  :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester