Avatar billede jackass- Nybegynder
29. marts 2004 - 18:52 Der er 14 kommentarer og
1 løsning

Skriv,læs,valider værdi i registreringsdatabase

Hejsa..

Hmm jeg sidder og har lidt et problem med at læse/skrive i regdb. Som I kan se herunder, forsøger jeg dels at læse/tjekke en værdi - samt a skrive/overskrive denne værdi. Problemet er lidt, at den tilsyneladende ikke gør nogen af delene, men den kommer heller ikke med fejl.

Er der nogen der kan fortælle/vise mig hvad der er galt?

/Jack
------------------------------------------

var
  key: HKey;
  cb: Longint;
  SubKey,Value: String;

Begin
  sumip := Edit1.Text + '.' + Edit3.Text + '.' + Edit3.Text + '.' + Edit4.Text; {en ip, fx 212.242.40.3}
  key := HKEY_LOCAL_MACHINE;
  SubKey := 'SOFTWARE\MyProg'+#0;
  if RegQueryValue(Key,@Subkey[1],@Value[1],cb) = ERROR_SUCCESS Then
    showmessage('Værdien er: '+Value)  {Hvis den eksisterer}
  else
    Begin
      Value := '212.242.40.3'+#0;
      if RegSetValue(Key,@SubKey[1],REG_SZ,@Value[1],Length(Value)) = ERROR_SUCCESS Then
        showmessage('Værdi gemt!');
    end;
end.
Avatar billede jackass- Nybegynder
29. marts 2004 - 18:54 #1
copy/paste fejl.. det er naturligvis:

Value := sumip+#0;
Avatar billede doc404 Novice
29. marts 2004 - 19:13 #2
Tag et kig på TRegistry.. Den gør livet lidt nemmere
Avatar billede jackass- Nybegynder
29. marts 2004 - 21:34 #3
Jeg har kigget på TRegistry .. det er nok mig der er fatdum, men jeg kan ikke rigtigt finde rundt i den..

Er der nogen der har et par simple eksempler på hvordan man henholdsvis skriver og læser fra (i mit eksempel HKEY_LOCAL_MACHINE\SOFTWARE\MyProg) regdb'en?

På forhånd mange tak :)

/Jack
Avatar billede hrc Mester
29. marts 2004 - 22:06 #4
type
  TMyRec = packed record
    X, Y : integer;
    Visible : boolean;
  end;

procedure TfrmMain.btnReadClick(Sender: TObject);
var
  st : string;
  MyRec : TMyRec;
begin
  with TRegistry.Create do
    try
      // Placér default værdier her
      st := 'Mogens Camre';
      MyRec.X := 100;
      MyRec.Y := 130;
      MyRec.Visible := true;

      if OpenKeyReadOnly('Software\MyProg') then begin // Åbn read only
        if ValueExists('EnStreng') then
          st := ReadString('EnStreng');
        if ValueExists('BinData') then
          ReadBinaryData('BinData',MyRec,GetDataSize('BinData')); // Bruger GetDataSize!
      end;
    finally
      Free;
    end; // try
end;

procedure TfrmMain.btnWriteClick(Sender: TObject);
var
  st : string;
  MyRec : TMyRec;
begin
  // Fylder data i variablene
  st := 'Pelle Voigt';
  MyRec.X := 150;
  MyRec.Y := 200;
  MyRec.Visible := true;

  with TRegistry.Create do
    try
      if OpenKey('Software\MyProg',true) then begin // Bemærk, anden funktion
        WriteString('EnStreng',st);
        WriteBinaryData('BinData',MyRec,SizeOf(TMyRec)); // Bruger sizeof
      end;
    finally
      Free;
    end; // try
end;
Avatar billede hrc Mester
29. marts 2004 - 22:06 #5
Unitten som du skal inkludere hedder Registry
Avatar billede doc404 Novice
29. marts 2004 - 22:12 #6
tja, hrc leverer som sædvanlig det rigtig løsning inden vi pader kan få tastet færdig ;-)

En enkelt kommentar. Du skal have administrative rettigheder for at skriv under HKEY_LOCAL_MACHINE.

For at undgå problemer med at læse, kan du åbne med Reg.OpenKeyReadOnly(..)

/doc
Avatar billede hrc Mester
29. marts 2004 - 22:15 #7
Grunden til jeg bruger GetDataSize det ene sted og sizeof det andet er følgende: Jeg kunne jo godt have brugt SizeOf(TMyRec) for at bestemme hvor mange bytes der skulle læses, men hvan nu hvis jeg tilføjede endnu et felt til min record? Det ville ikke gå godt.

Jeg bruger tit en packed record til at gemme mine "default værdier" og skærmpositioner. I stedet for at hente læse Left, Top, Width, Height og et antal andre parametre een efter een, så henter jeg dem i et hurtigt hug vha. ReadBinaryData.
Eneste problem med den løsning er når jeg vil gemme strenge. Det er jo ikke smart at have en TMyRec der indeholder en streng på eksempelvis længden 255. Det er spild af plads, så dem placerer jeg ved siden af.
Alternativet er at streame strengene med en #0 imellem - men så kan man ligeså godt skippe registreringsdatabasen og lave sin egen fil. Vi skal jo ikke have den database til at vokse mere end højst nødvendig.

Efter try-linien skal du lige indføje "ROOT := HKEY_CURRENT_USER;"
Avatar billede hrc Mester
29. marts 2004 - 22:16 #8
he,he - jeg nåede det næsten (med ROOT'en)
Avatar billede hrc Mester
29. marts 2004 - 22:25 #9
doc404 - undskyld. Kunne se at det var 3 minutter siden at du skrev, og så troede jeg ikke du gad svare ;-)

Det hedder RootKey, ikke ROOT.

Vil i den forbindelse gerne beklage min upædagogiske skik med at bruge "with" istedet for at lave en variabel. Det er ikke altid let at finde ud af hvilke kommandoer der hører til objektet og hvilke der ikke gør - så nu laver jeg et pædagogisk eksempel:

procedure TfrmMain.btnWriteClick(Sender: TObject);
var
  st : string;
  MyRec : TMyRec;
  Reg : TRegistry;
begin
  // Fylder data i variablene
  st := 'Pelle Voigt';
  MyRec.X := 150;
  MyRec.Y := 200;
  MyRec.Visible := true;

  Reg := TRegistry.Create(KEY_ALL_ACCESS); // Bemærk, en overloadet constructor.
  try
    Reg.RootKey := HKEY_CURRENT_USER; // Den glemte jeg
    if Reg.OpenKey('Software\MyProg',true) then begin // Bemærk, anden funktion
      Reg.WriteString('EnStreng',st);
      Reg.WriteBinaryData('BinData',MyRec,SizeOf(TMyRec)); // Bruger sizeof
    end;
  finally
    Reg.Free;
  end; // try
end;
Avatar billede jackass- Nybegynder
30. marts 2004 - 05:48 #10
Hvor kommer det her fra?

  MyRec.X := 150;
  MyRec.Y := 200;

Jeg kan godt generelt se hvad der sker, men der er et par af tingene der ikke virker logiske - to me anyways hehe?
Avatar billede hrc Mester
30. marts 2004 - 10:42 #11
Hvis du kigger i mit første indslag kan du se at jeg definerer en TMyRec-record type med felterne X,Y,Visible. Hverken st eller MyRec har funktionel betydning idet de defineres inde i procedurerne. Kun demonstration.

Disse 3 variable data fylder nogle bytes og i stedet for at gemme dem enkeltvis:

  Reg.WriteInteger('X',MyRec.X);
  Reg.WriteInteger('Y',MyRec.Y);
  Reg.WriteBool('Visible',MyRec.Visible);

så gemmer jeg dem som binære data:

  WriteBinaryData('BinData',MyRec,SizeOf(TMyRec));

Jeg sparer her to skrivninger til registreringsdatabasen. I større programmer har jeg måske 25 værdier, gemt i en record, som jeg håndterer på denne måde og så er det meget hurtigere.
Avatar billede jackass- Nybegynder
30. marts 2004 - 17:40 #12
hrc, tusind tak for din hjælp.. jeg kludrer dog stadig rundt i det .. sorry jeg er newbie. Kan jeg lokke dig til at lave den færdige kode for mig.. ved godt det ikke normalt er noget man gør, men jeg er sgu lidt lost og tror ikk jeg kan fatte det før jeg ser det virke i mit eksemmmpel.. vil godt give ekstra points for det hvis det er :(

Mine data skal ligge i HKEY_CURRENT_USER\Software\SysPing .. og der skal så være en key der fx hedder IP som er = 212.242.40.3

Min TForm2.Button1Click(Sender: TObject); skal så noget i den her stil (newbie pseudo kode hehe):


if exists(værdien i IP key'en) then
  var result := 'den værdi';
  showmessage(result);

{og så skrive den ny-indtastede værdi ind som er en var sumip:string ind - enten overskrive eller lave den key hvis den ikke eksisterer}


Dvs der er 2 dele i det:
1) den skal checke om den key er der, og hvis den er så showmessage(værdien)
2) en anden string værdi som er en variabel der hedder sumip skal så skrives/overskrive den gamle værdi.

På forhånd 100000000 tak :)

/Jack @ newbie.dk da.. :/
Avatar billede jackass- Nybegynder
30. marts 2004 - 22:35 #13
Ah efter lang tids roderi blev jeg endelig klogere :P

Så spiller det! ;)
Avatar billede hrc Mester
31. marts 2004 - 12:40 #14
Jeg lavede en funktion til begge opgaver (glemte bare RootKey i begge). Bemærk, at fSumIP er en streng-variabel gemt i den private del af formen.

procedure TfrmMain.btnReadClick(Sender: TObject);
begin
  with TRegistry.Create do
    try
      Reg.RootKey := HKEY_CURRENT_USER;
      if OpenKeyReadOnly('Software\SysPing') then  // Åbn read only
        if ValueExists('sumip') then
          fSumIP := ReadString('sumip');
    finally
      Free;
    end; // try

  MessageDlg('IP: '+fSumIP,mtInformation,[mbOK],0);
end;

procedure TfrmMain.btnWriteClick(Sender: TObject);
begin
  with TRegistry.Create do
    try
      if OpenKey('Software\SysPing',true) then // Bemærk, anden funktion
        WriteString('SumIP',fSumIP);
    finally
      Free;
    end; // try
end;
Avatar billede hrc Mester
31. marts 2004 - 12:41 #15
Jeg glemte naturligvis

  Reg.RootKey := HKEY_CURRENT_USER;

i den nederste procedure...
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