Autor |
Beitrag |
Xearox
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: So 24.02.13 02:43
Folgendes Problem,
ich finde hier in der Entwickler Ecke und in delphi praxis etc. immer nur Beispiele, wie ich eine Variable von einer form unit an eine andere übergebe.
Nun habe ich aber ein unit ganz ohne Form, also eine reine .pas und hier fängt mein Problem an.
Bisher habe ich die Variable in public deklariert, wenn ich diese irgendwo anders noch verwenden will, allerdings scheint dies nicht in einer reinen Unit zu funktionieren.
Entweder fehlt mir etwas bei den uses oder es ist einfach nicht möglich, ich bitte um Hilfe.
Hier mein Sourcecode:
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: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| unit init;
interface
uses SysUtils,Dialogs,IniFiles;
procedure Programmstart; procedure Programmstop;
implementation uses Main,setting,SpielUnit;
var resH,resW : integer; procedure Programmstart; var ini : TIniFile; filename : String; begin if FileExists(ExtractFilePath(ParamStr(0)) + '\config\' + 'setting.ini') then begin filename := ExtractFilePath(ParamStr(0)) + '\config\' + 'setting.ini'; ini := TIniFile.Create(filename); try resW := ini.ReadInteger('Fenstergröße', 'Breite', 0); resH := ini.ReadInteger('Fenstergröße', 'Höhe', 0);
Showmessage('Config erfolgreich geladen'); finally ini.Free; end; end else Showmessage('Datei nicht vorhanden'); end; procedure Programmstop; var ini : TIniFile; filename : String; begin filename := ExtractFilePath(ParamStr(0)) + '\config\' + 'setting.ini'; ini := TIniFile.Create(filename); try if (Form3.resH <> 0) and (Form3.resW <> 0) then begin ini.WriteInteger('Fenstergröße', 'Breite', form3.resW); ini.WriteInteger('Fenstergröße', 'Höhe', form3.resH); end;
ini.WriteInteger('Fensterposition', 'X', 0); ini.WriteInteger('Fensterposition', 'Y', 0);
Showmessage('Config erfolgreich gespeichert'); finally ini.Free; end; end;
end. |
Und selbst verständlich habe ich in den anderen Units die Unit "init" bei in den uses eingefügt!
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:
| unit Main;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, iniFiles;
type TForm1 = class(TForm) Label1: TLabel; BtSpielstarten: TButton; BtClose: TButton; Btsetting: TButton; procedure BtCloseClick(Sender: TObject); procedure BtSpielstartenClick(Sender: TObject); procedure BtsettingClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); private public var resH,resW : integer; end;
var Form1: TForm1;
implementation uses init, SpielUnit, setting; |
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 02:50
Was unter implementation steht, ist nur in der eigenen Unit sichtbar. Verschieb also einfach die globalen Variablen in den interface-Abschnitt. Über Sinn und Unsinn globaler Variablen lasse ich mich hier jetzt nicht aus.
|
|
Xearox 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: So 24.02.13 02:58
Mensch das geht echt fix bei dir =)
Ich danke dir noch mal =)
Ja ich weiß, hab schon des öfteren gelesen, das globale variablen nicht gerne gesehn sind.
Allerdings weiß ich nicht, wie ich es anders realisieren kann, da wenn ich innerhalb der init folgenden code aufzurufen:
Delphi-Quelltext 1: 2: 3: 4:
| ... form2.Height := resH; form2.Width := resW; ... |
erhalte ich eine EAccessviolation exception. Und ich denke auch warum ich die erhalte, da Form2 noch nicht erstellt wurde, da das beim OnCreate von Form1 ausgeführt wird. Vermute ich mal ganz stark.
Anders kann ich mir den Fehler nicht erklären.
Allerdings, wenn du mir da eine Hilfestellung geben könntest, wie ich die Einstellungen aus der config.ini global auf alle Forms übertragen kann, wäre ich dir sehr dankbar =)
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 24.02.13 03:07
|
|
Xearox 
      
Beiträge: 260
Erhaltene Danke: 3
|
Verfasst: So 24.02.13 03:21
WasWeißDennIch hat folgendes geschrieben : | Wie wäre es denn z.B. mit einer Routine, die die entsprechende Formularinstanz als Parameter entgegennimmt? Pseudo-Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure LoadFormSettings(aForm: TForm); var IniName: string; Ini: TIniFile; begin Assert(Assigned(aForm), 'Kein Formular übergeben'); IniName := <irgendwie zusammengesetzt>; Ini := TIniFile.Create(IniName); try aForm.Width := Ini.ReadInteger(aForm.Classname, 'resW', 1024); aForm.Height := Ini.ReadInteger(aForm.Classname, 'resH', 768); finally Ini.Free; end; end; |
Im OnCreate oder so des jeweiligen Formulars rufst Du dann diese Routine auf:
Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm2.FormCreate(Sender: TObject); begin LoadFormSettings(self); end; | |
Das funktioniert super =) Hab das ein wenig an meine Bedürfnisse angepasst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure LoadFormSettings(aForm: TForm); var IniName: string; Ini: TIniFile; begin Assert(Assigned(aForm), 'Kein Formular übergeben'); IniName := ExtractFilePath(ParamStr(0)) + '\config\' + 'setting.ini'; Ini := TIniFile.Create(IniName); try aForm.Width := Ini.ReadInteger('Fenstergröße', 'Breite', 0); aForm.Height := Ini.ReadInteger('Fenstergröße', 'Höhe', 0); finally Ini.Free; end; end; |
Ich muss aber ehrlich gestehn, damit habe ich bisher noch nicht gearbeitet.
Delphi-Quelltext 1:
| Assert(Assigned(aForm), 'Kein Formular übergeben'); |
Also mit Assert hab ich bis dato noch nie mit gearbeitet. Bin mir grade paar sachen am raus suchen, wo das genau erklärt ist, was man mit Assert machen kann.
Auch wenn ich schon so einiges geschrieben habe, habe ich das immer so umständlich gemacht. Ganz am Anfang, als ich mit dem Programmieren angefangen habe, hab ich das alles noch mit Const gemacht, da wusste ich noch nicht mal, wie man eine ini anlegt.
Allerdings ist mein Motto: learning by doing
Deswegen suche ich mir immer neue Herausforderungen, um mich dann weiter zu bilden.
|
|
MeierZwoo
      
Beiträge: 94
Erhaltene Danke: 11
Win 7, DOS5
Delphi 2007 Architect, BP7/TP5, LISP, PS
|
Verfasst: So 24.02.13 03:52
WasWeißDennIch hat folgendes geschrieben : | Über Sinn und Unsinn globaler Variablen lasse ich mich hier jetzt nicht aus. |
Das lese ich hier und anderswo ständig. Nur, wie bitte will man ohne globale Variablen und Const denn programmweite Paramter setzen? Gerade Initialisierungs-Parameter sind typische Vertreter globaler Werte.
Ich kann nichts erkennen, was globale Werte so »böse« erscheinen läßt. Nicht nur, daß ohne diese die meisten Proceduren und Functionen einen riesigen Rattenschwanz von Parameterlisten erzwingen würden, bei einigen, zB den oben erwähnten Initialisierungs-Parametern würde ich nicht einmal wissen, wie die dann überhaupt das erste mal übergeben werden sollten, um sie dann als Rattenschwanz weiter geben zu können.
Wenn dem so wäre, dürften ja auch keine globalen Classen, Objekte .. benutzt werden.
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 24.02.13 09:35
MeierZwoo hat folgendes geschrieben : | WasWeißDennIch hat folgendes geschrieben : | Über Sinn und Unsinn globaler Variablen lasse ich mich hier jetzt nicht aus. |
Das lese ich hier und anderswo ständig. Nur, wie bitte will man ohne globale Variablen und Const denn programmweite Paramter setzen? Gerade Initialisierungs-Parameter sind typische Vertreter globaler Werte.
Ich kann nichts erkennen, was globale Werte so »böse« erscheinen läßt. Nicht nur, daß ohne diese die meisten Proceduren und Functionen einen riesigen Rattenschwanz von Parameterlisten erzwingen würden, bei einigen, zB den oben erwähnten Initialisierungs-Parametern würde ich nicht einmal wissen, wie die dann überhaupt das erste mal übergeben werden sollten, um sie dann als Rattenschwanz weiter geben zu können.
Wenn dem so wäre, dürften ja auch keine globalen Classen, Objekte .. benutzt werden. |
Dem kann ich nur zustimmen. Denn eines ist man klar: starre Regeln führen immer zu Dogmatismus, und der ist bekanntlich in sich verkehrt, wie man ja aus dem politischen Leben sehen kann. Es geht m.E. immer darum, dass man die möglichen Konsequenzen bedenkt und einen Wildwuchs an globalen Variablen vermeidet. Manchmal lohnt es sich schon, da etwas mehr Grips reinzustecken, und das Problem, das man gerade hat, anders als mit globalen Variablen zu lösen. Das muss jeder mit sich selber ausmachen, wo da seine Grenzen sind. In einem Team sieht das sicher anders aus, denn da ist ja jeder vom anderen abhängig, so dass Regeln-Brechen möglichgerweise fatale Folgen haben kann. Aber auch da kann man das ganze ja kommunizieren, oder? Da ja die meisten hier "Alleinprogrammierer" sind (Ausnahmen bestätigen oft die Regel  ), ist das Thema zweitrangig und müsste nicht immer erwähnt werden. Zudem mag ich persönlich die erhobenen Zeigefinger weniger. Aber jetzt beziehe ich sicher gewaltig Mecker!!!
Oder wie hieß es beim Pirat der Karibik:
Das sind doch eher Richtlinien!
In dem Sinne, ein bisschen weniger Dogmatismus bitte. 
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
|