Entwickler-Ecke

Sonstiges (Delphi) - Was is FALSCH??? :(


Experience1986 - Di 04.02.03 10:53
Titel: Was is FALSCH??? :(
Hi,

Ich hab da ne reihe an abfragen, diese werden durch Radion Button ausgelöst. Wenn ein Schlüssel in der Registry vorhanden ist, dann sollt ein Wert in diesem Schlüssel gespeichert werden.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
procedure TForm1.RadioButton2Click(Sender: TObject);
var regist: TRegistry;
begin
          regist.RootKey := HKEY_CURRENT_USER;


          if regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', True) then
          begin
          regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', true);
          regist.WriteInteger('MinToTray', 1);
          regist.free;
          end;


          if regist.OpenKey('Software\Microsoft\Office\9.0\Outlook\Preferences', True) then
          begin

          regist.WriteInteger('MinToTray', 1);
          regist.free;
          end;

          if regist.OpenKey('Software\Microsoft\Office\8.0\Outlook\Preferences', True) then
          begin
          regist.OpenKey('Software\Microsoft\Office\8.0\Outlook\Preferences', true);
          regist.WriteInteger('MinToTray', 1);
          regist.free;
          end;
end;



procedure TForm1.RadioButton1Click(Sender: TObject);
var regist: TRegistry;
begin
  regist:=TRegistry.Create;
   regist.RootKey:=HKEY_CURRENT_USER;

          if regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', True) then
          begin
          regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', true);
          regist.WriteInteger('MinToTray', 0);
          regist.free;
          end;


          if regist.OpenKey('Software\Microsoft\Office\9.0\Outlook\Preferences', True) then
          begin

          regist.WriteInteger('MinToTray', 0);
          regist.free;
          end;

          if regist.OpenKey('Software\Microsoft\Office\8.0\Outlook\Preferences', True) then
          begin
          regist.OpenKey('Software\Microsoft\Office\8.0\Outlook\Preferences', true);
          regist.WriteInteger('MinToTray', 0);
          regist.free;
          end;
end;


Leider funktioniert das jetzt nicht :(
Was ist daran Falsch?


Tino - Di 04.02.03 10:57

Hi,

Du musst Die Variable regist auch initialisieren:

Quelltext
1:
2:
3:
4:
procedure TForm1.RadioButton2Click(Sender: TObject); 
var regist: TRegistry; 
begin 
  regist := tRegistry.Create;

Am Schluß Deiner Procedure musst Du die regist Variable wieder freigeben:

Quelltext
1:
2:
  regist.Free;
End;


Gruß
TINO

PS: Bitte ließ Dir die Richtlinien durch. Speziell folgender Absatz:
Richtlinien hat folgendes geschrieben:
1.1 Beiträge

Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.


Delete - Di 04.02.03 11:10

Auch wenn ich nerve oder so. Aber ich sage nur Ressourcen-Schutzblock. :roll:


Udontknow - Di 04.02.03 11:25

Ja, kann man gar nicht oft genug sagen.
TRY / FINALLY ist bei temporären Objekterstellungen immer sinnvoll.

Cu,
Udontknow


Experience1986 - Di 04.02.03 13:34

Ubnd wie würde man das Resourcen SParend coden?


Delete - Di 04.02.03 13:39

Zuerst mal das

Quelltext
1:
regist.RootKey := HKEY_CURRENT_USER;                    

weglassen. Der Schlüssel wird sowieso standardmäßig benutzt. Und dann geht´s nicht um Ressourcen sparen, sondern um eine vernünftige Programmierung. Und die sieht zusammengefasst so aus:

Quelltext
1:
2:
3:
4:
5:
6:
regist := TRegistry.Create;
try
  { ... }
finally
  regist.Free;
end;

Die ganzen Anweisungen

Quelltext
1:
regist.Free;                    

die sich in deinem Code tummeln, solltest du entfernen und durch

Quelltext
1:
regist.CloseKey;                    

ersetzen! "regist.Free" wird nur einmal aufgerufen - nämlich dann, wenn du die Registry geschlossen hast und nicht mehr darauf zugreifst!

Und noch ein Beispiel für besondere Sinnlosigkeit:

Quelltext
1:
2:
3:
4:
5:
if regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', True) then
  begin
    regist.OpenKey('Software\Microsoft\Office\10.0\Outlook\Preferences', true);

{ ... }

Der Schlüssel ist bereits offen, notfalls wird er sogar erzeugt. Warum öffnest du ihn also nochmal?


Delete - Di 04.02.03 13:53

Nachtrag: Mit etwas Nachdenken lässt sich der komplette Code von Experience1986 auf ca. 10 Anweisungen kürzen (nicht eingerechnet die Zeilenumbrüche, die ich mir mittlerweile angewöhnt habe, damit der Code nicht zu breit wird). :wink:

Soll ich vormachen? Oder kommt ihr selbst drauf?


smiegel - Di 04.02.03 14:08

Hallo,

@MathiasSimmack,

in etwa so?


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
resourcestring
  rsSoftware='Software\Microsoft\Office\';
  rsOutlook ='\Outlook\Preferences';

procedure DoUpdateRegistry(AnAus:Integer); 
var regist: TRegistry; 
begin
  regist:=TRegistry.Create;
  with regist do
  try
    RootKey:=HKEY_CURRENT_USER; 
    if OpenKey(rsSoftware+'10.0'+rsOutlook, False) then WriteInteger('MinToTray', AnAus); 
    if OpenKey(rsSoftware+'9.0'+rsOutlook, False) then WriteInteger('MinToTray', AnAus); 
    if OpenKey(rsSoftware+'8.0'+rsOutlook, False) then WriteInteger('MinToTray', AnAus); 
  finally
    Free;
  end; // try, with
end; // DoUpdateRegistry


procedure TForm1.RadioButton2Click(Sender: TObject);
begin
  DoUpdateRegistry(1);
end; 

procedure TForm1.RadioButton1Click(Sender: TObject);
begin
  DoUpdateRegistry(0);
end;


Delete - Di 04.02.03 15:01

Das sind die Fragen, die Günther Jauch nie stellt. :wink:

@smiegel: Es kommt meiner Idee schon ziemlich nahe. :) Aber du solltest einen Schlüssel auch wieder schließen, bevor du auf den nächsten zugreifst. Und mit den Versionsnummern von Office lässt sich doch auch was machen, nicht wahr? :idea:


smiegel - Di 04.02.03 15:16

Hallo,

MathiasSimmack hat folgendes geschrieben:

... einen Schlüssel auch wieder schließen, ...

Habe bisher noch keine negativen Erfahrungen dazu gemacht. Spätestens bei reg.Free, werden sie (alle) geschlossen.

MathiasSimmack hat folgendes geschrieben:

... mit den Versionsnummern von Office lässt sich doch auch was machen

Sicher, in einer Schleife mit Format (oder hast Du da etwas anderes im Auge?).


Deine Anregungen umgesetzt, müsste dann ja das herauskommen?

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
resourcestring 
  rsOutlook='Software\Microsoft\Office\%d.0\Outlook\Preferences'; 

procedure DoUpdateRegistry(AnAus:Integer); 
var regist: TRegistry; 
      i:Integer;
begin 
  regist:=TRegistry.Create; 
  with regist do 
  try 
    RootKey:=HKEY_CURRENT_USER; // --> evtl. überflüssig
    for i:=8 to 10 do if OpenKey(Format(rsOutlook, [i]), False) then 
    begin
      WriteInteger('MinToTray', AnAus); 
      CloseKey;
    end; // for i
  finally 
    Free; 
  end; // try, with 
end; // DoUpdateRegistry


Delete - Di 04.02.03 15:37

smiegel hat folgendes geschrieben:
Deine Anregungen umgesetzt, müsste dann ja das herauskommen?

Perfekt. :D Du hast wohl irgendwie in meine Notepad-Datei geschmult, die ich schon vorbereitet hatte? Ich habe nämlich auch an "Format" gedacht.

Nur zwei Dinge:


smiegel - Di 04.02.03 15:51

Hallo,

MathiasSimmack hat folgendes geschrieben:

Den Ressourcestring "rsOutlook" kannst du dir sparen; ...

Da hast Du vollkommen Recht.
Ich habe mir aber angewöhnt, generell im Programm vorkommenden Strings als Konstante zu deklarieren. Mir kommt es weniger auf Ressourcen sparen, als auf Übersichtlichkeit an.

MathiasSimmack hat folgendes geschrieben:

... in meine Notepad-Datei geschmult, ...


Klar, mache ich ständig. Hab' mir ein kleines Prog geschrieben, welches bei allen Rechnern, deren User sich im Forum herumtreiben, die Festplatte ausliest :wink:


Delete - Di 04.02.03 19:04

smiegel hat folgendes geschrieben:
Ich habe mir aber angewöhnt, generell im Programm vorkommenden Strings als Konstante zu deklarieren.

Das mache ich nur -wenn überhaupt!- bei Strings, die man ggf. in andere Sprachen übersetzen kann/will/muss. Dafür ziehe ich ebenfalls sämtliche Meldungen usw. an den Anfang des Programms und deklariere sie als Konstanten.

Aber für fixe Registrypfade, die auch auf anderssprachigen Win-Versionen Gültigkeit haben, lohnt sich das IMHO nicht. Es sei denn (wie gesagt!), ich muss den jeweiligen String mehrfach verwenden. Dann deklariere ich ihn auch als Konstante, lasse ihn aber (wenn möglich) lokal in der Funktion, bzw. setze ihn vor die Funktionen, in denen er gebraucht wird.


Experience1986 - Di 04.02.03 19:48

Was heist Strings als Konstante?

Und ich will jetzt einen vorhandenen Registryeintrag vergleichen, und wenn er da ist, dann soll eine RadioBox aktiviert werden (checked), wie macht man das?

Ich weis, ich stelle viele fragen, aber ich wioll es lernen ;-)

Aber eure hilfe ist echt Mega gut und ich bi euch auch dafür sehr dankbar


smiegel - Di 04.02.03 20:03

Hallo,


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function IstDa(const aRegKey:String):Bool;
var aReg:TRegistry;
begin
  aReg:=TRegistry.Create;
  with aReg do
  try
    Result:=OpenKey(aRegKey, False);
  finally
    Free;
  end;
end; // IstDa

  ...
  ...
  RadioButton1.Checked:=IstDa('Software\Microsoft\Office\10.0\Outlook\Preferences');
  ...
  ...


Delete - Di 04.02.03 20:17

Nicht ganz, @smiegel. Es ging ja um einen Registryeintrag, nicht -schlüssel. Und ich vermute mal, Experience1986 will den auslesen, den er mit obigem Code aktiviert.

@Experience: Das Prinzip entspricht im Prinzip dem Setzen des Wertes. Du kannst auch wieder die for-Schleife benutzen, um versionsabhängig den Schlüssel zu öffnen (8 - 10).
Dann prüfst du mit "ValueExists", ob der gesuchte Wert vorhanden ist. Wenn dir das nicht reicht und du wissen möchtes, ob der Wert auch den erwarteten Inhalt hat (0, 1), dann liest du ihn noch aus.

Zitat:
Was heist Strings als Konstante?

Die Texte bitte genau lesen!
Das bedeutet, dass man Strings, die man mehrfach nutzen möchte, an einer Stelle als Konstante deklarieren kann:

Quelltext
1:
2:
const
  rsOutlook = 'Software\Microsoft\...';

und dann benutzt du nur noch diese Konstante. Vorteil: eine Änderung an der Konstante aktualisiert das ganze Programm, und du musst nicht mühsam den Quellcode durchsuchen, ob der String irgendwo verwendet wurde.


Tino - Mi 05.02.03 10:22

@Experience1986: Könntest Du bitte den Titel diese Topics in einen sinnvollen Titel ändern. Einfach auf Dein erstes Posting auf Edit klicken und den Titel ändern. Danke!

Gruß
TINO