function hoch_nat(x: real; n:integer): real; //n kein Bruch! begin if n < 0 then result := 1/hoch_nat(x,-n) else if n = 0 then result := 1 else result := x*hoch_nat(x,n - 1) end; function hoch(x,n: real): real; begin if n = 0 then result := 1 //hier also 0^0 = 1 siehe Bemerkung else if x = 0 then result := 0 else if frac(n) = 0 then result := hoch_nat(x,round(n)) // x < 0 else result := Exp(n*Ln(x)) //n Bruch oder irrational //nur für x > 0 end;Achtung: Zum Beispiel hoch(-2,0.5) ist nicht erlaubt.
In Pascal ist die Funktion xn nicht als Standardfunktion implementiert. Der Programmierer muss sich selbst klar werden, wie er diese Funktion verwendet (Zum Beispiel für neagatives x, dann aber n nur ganzzahlig).0 0 0 Bemerkung: 0 kann definiert werden als 0 = 1 und 0 = 0 ohne den algebraischen Potenzgesetzten zu widersprechen: x x x x x+y x y x y x*y (a ·b ) = a * b a = a *a (a ) = a 0 Als Grenzwert kann man 0 auf zwei Arten gewinnen. 0 0 0 0 0 0 0 = lim x = 1 Zum Beispiel: 2 = 1 = (1/2) = (1/100) = ... = 1 x->0 0 x 2 1 (1/2) (1/100) 0 = lim 0 = 0 Zum Beispiel: 0 = 0 = 0 = 0 = ... = 0 x->0+ 0 In der Kombinatorik ist 0 = Anzahl der Abbildungen von {} auf {} = 1.
Zum besseren Verständnis erläutere ich es nicht im Dualsystem (Basis = 2) mit der Mantissenlänge 32 sondern im Zehnersystem (Basis=10) mit der Mantissenlänge 5. Mit der Mantisse 54321 und dem Exponenten 3 wird die Zahl 5,4321·103 dargestellt. Der besseren Lesbarkeit schreibe ich dafür 5,4321·1000 Es wird also gerundet gerechnet. Beispielsweise werden die Zahlen 5432,05 und 5432,149 auf 5432,1 gerundet. (Nebenbei bemerkt: Die meisten Programmiersprachen speichern ihre Zahlen im Dualsystem und runden daher nicht immer kaufmännisch!) Bei Mantissenlänge 5 beträgt der Fehler zum exakten Wert maximal 0,005% Je nach Rechnung kann der Fehler unerwartet schnell anwachsen. Beispiel: Wir vergleichen a·a - b·b und (a+b)·(a-b) für a = 45,431 und b= 45,421 a·a - b·b in Gleitkommaarithmetik ergibt a·a = 4,5431·10 · 4,5431·10 = 2,0640·1000 b·b = 4,5421+10 · 4,5421·10 = 2,0631·1000 ————————————————————————————————————————— I a·a - b·b = 9,0000·1/10 a + b = 4,5431·10 + 4,5421·10 = 9,0852·10 a - b = 4,5431·10 - 4,5421·10 = 1,0000·1/100 ———————————————————————————————————————————— II (a+b)·(a-b) = 9,0852·1/10 Exakt a·a - b·b = (a+b)·(a-b) = 0,90852 Fehler bei Rechnung I fast 1%, bei Rechnung II 0%Eine gute Erkenntnis dazu kann auch jeder mit dem Taschenrechner, der auch mit der Gleitkommaarithmetik rechnet, nachvollziehen:
(1.00 + 0.004) + 0.004) = 1.00 1.00 + (0.004 + 0.004) = 1.01 -3 Beachte: 0.004 = 4·10 hat die Mantisse 4 und als Exponent -3!Ein drastisches Beipiel liefert die Addition 1.00 + 0.001 + 0.001 + .... + 0.001 (1000 mal)
uses shellapi; function IniPfad:string; var exepfad, exefile: string; begin exepfad := extractFilepath(paramstr(0)); exefile := extractFilename(paramstr(0)); result:=exepfad //der exe-pfad des Programms + copy(exefile,1,length(exefile) - 3) //der Name ohne "exe" + 'ini'; //die Ini-Datei end; procedure TForm1.FormCreate(Sender: TObject); begin with Form1 do Begin caption:='Programm Starten'; label1.Caption:='Klicke "Neu" oder das Programm an. Dann "OK"!'; label2.Caption:= 'evtl. Parameter'; try memo1.Lines.LoadFromFile(Inipfad); except {bis aufs erste Mal} End; End; end; procedure TForm1.FormDestroy(Sender: TObject); begin try memo1.Lines.SaveToFile(Inipfad); except {keine Schreibrechte} End; end; procedure TForm1.Schlieen1Click(Sender: TObject); begin close; end; function spacesf(n:integer):string; //n beliebig ! const s=' '; //Achtung spacec ————————————————————————————————————————————> begin result:=copy(s,1,n); while length(result) < n do result:=result+copy(s,1,n-length(result)); end; //Bemerkung: In Delphi kann man StringOfChar(' ',n) verwenden. function glSpf(s:string):boolean; begin result:=(s=spacesf(length(s))); end; procedure loescheleerezeilen(m:TMemo); var k:integer; begin k := 0; while k < m.Lines.Count do if glspf(m.lines[k]) then m.Lines.Delete(k) else inc(k) end; procedure TForm1.Neu1Click(Sender: TObject); begin with opendialog1 do Begin options:=[ofFileMustExist,ofAllowMultiselect,ofHideReadOnly,ofShareAware, ofEnableSizing, ofNoTestFileCreate,ofNoValidate]; Filter :='EXE-Dateien (*.exe)|*.exe|Batchdateien (*.bat)|*.bat|' +'Alle Dateien (*.*)|*.*'; DefaultExt:='exe'; End; if opendialog1.Execute then Begin edit1.text := opendialog1.filename; if pos(edit1.text,Memo1.Text) = 0 then Memo1.lines.add(edit1.text); loescheleerezeilen(memo1); End; end; function ShellexecuteFehler(i: integer): string; begin Case i of 0: result := 'The operating system is out of memory or resources.'; ERROR_FILE_NOT_FOUND: result := 'The specified file was not found.'; ERROR_PATH_NOT_FOUND: result := 'The specified path was not found.'; ERROR_BAD_FORMAT: result := 'The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).'; SE_ERR_ACCESSDENIED: result := 'The operating system denied access to the specified file.'; SE_ERR_ASSOCINCOMPLETE: result := 'The filename association is incomplete or invalid.'; SE_ERR_DDEBUSY: result := 'The DDE transaction could not be completed because other DDE transactions were being processed.'; SE_ERR_DDEFAIL: result := 'The DDE transaction failed.'; SE_ERR_DDETIMEOUT: result := 'The DDE transaction could not be completed because the request timed out.'; SE_ERR_DLLNOTFOUND: result := 'The specified dynamic-link library was not found.'; //SE_ERR_FNF : result:='The specified file was not found.'; SE_ERR_NOASSOC: Begin //result:='Unbekannter Extender. TTW versucht einzulesen.'; //if gg then exit; //Dateidazu(pfadplusname) End; SE_ERR_OOM: result := 'There was not enough memory to complete the operation.'; //SE_ERR_PNF : result:='The specified path was not found.'; SE_ERR_SHARE: result := 'A sharing violation occurred.'; End; end; procedure programmstarten(pfad, parameter: string); var name: String; code: integer; begin name := extractFilename(Pfad); pfad := extractFilepath(pfad); //Jetzt nur Pfad code := ShellExecute(application.handle, Pchar('open'), Pchar(name), Pchar(Parameter), Pchar(Pfad), sw_ShowNormal); if code < 32 then showmessage(ShellexecuteFehler(code)); end; procedure TForm1.Ok1Click(Sender: TObject); var n:integer; begin programmstarten(edit1.text, edit2.text); end; function ZeileDesCursorsI(ed: TCustomEdit): integer; var k: integer; s: string; begin s := ed.Text; //ohne schafft es der Comp. nicht result := 1; for k := 1 to ed.Selstart do if s[k] = #13 then inc(result); end; function ZeileDesCursorsS(ed: TCustomMemo): string; var i: integer; begin i := ZeileDesCursorsI(ed) - 1; if ed.Lines.count > i then result := ed.lines[i] else result := ''; end; procedure TForm1.Memo1Click(Sender: TObject); begin edit1.text := ZeileDesCursorsS(Memo1) end;
procedure zeichneKreis(canv: Tcanvas; x, y, r: integer; farbeRand, farbeInnen:Tcolor); begin with canv do Begin Pen.Color := farbeRand; Pen.Width := 5; Brush.Style := bssolid; Brush.Color := farbeInnen; Ellipse(x-r,y-r,x+r,y+r) End end; procedure TForm1.Button1Click(Sender: TObject); var w, h:integer; begin w := form1.Width; h := form1.Height; zeichneKreis(canvas, w div 2, h div 2, h div 4, clblack, clred); sleep(1000); zeichneKreis(canvas, w div 2, h div 2, h div 4, color, color); //hier canvas = Form1.canvas und color = Form1.color end;Erläuterungen: Canvas ist die "Zeichne-Eigenschaft" von Form1 oder image1 u.s.w.
procedure zeichneKreis(canv: Tcanvas; x, y, r: integer; farbeRand, farbeInnen:Tcolor); begin with canv do Begin Pen.Color := farbeRand; Pen.Width := 5; Brush.Style := bssolid; Brush.Color := farbeInnen; Ellipse(x-r,y-r,x+r,y+r) End end; procedure TForm1.Button1Click(Sender: TObject); var w, h:integer; begin w := image1.Width; h := image1.Height; zeichneKreis(image1.canvas, w div 2, h div 2, h div 4, clblack, clred); application.ProcessMessages; //Wichtig: Es soll gleich gezeichnet werden! sleep(1000); zeichneKreis(image1.canvas, w div 2, h div 2, h div 4, clwhite, clwhite); end;Beispiel Graphik3
uses //Schrieb Delphi Clipbrd, jpeg, //Musst Du einfügen Windows, Messages, ...//schrieb Delphi var Form1: TForm1; //Schrieb Delphi EsWirdGezeichnet : Boolean = false; //Deine globale Variable //... procedure TForm1.ZeichneClick(Sender: TObject); //Menü begin showmessage('Mausklick und ziehen!'); end; procedure TForm1.BildindieZwischenablage1Click(Sender: TObject);//Menü begin Clipboard.Assign(image1.Picture.Bitmap); //"uses Clipbrd" end; procedure TForm1.BildausderZwischenablageholen1Click(Sender: TObject); begin image1.Picture.Assign(Clipboard); //"uses Clipbrd" //Größe des Bildes noch anpassen image1.Height := image1.Picture.Bitmap.Height; image1.Width := image1.Picture.Bitmap.Width; end; procedure TForm1.BMPspeichern1Click(Sender: TObject);//Menü begin with SaveDialog1 do Begin Options:=[ofCreatePrompt,ofEnableSizing,ofHideReadOnly,ofShareAware,ofEnableSizing]; //Ohne Kästchen Filter :='Bitmap-Dateien (*.bmp)'; filename := ChangeFileExt(filename, '.bmp'); DefaultExt:='bmp'; if execute then Begin image1.Picture.SaveToFile(Filename); End else showmessage('Nicht gespeichert'); End; end; procedure TForm1.JPEGspeichern1Click(Sender: TObject);//Menü var jpg :TJPEGImage; //benötigt "uses jpeg" begin jpg:=TJPEGImage.Create; try jpg.Assign(image1.Picture.Bitmap); jpg.CompressionQuality := 90; //Qualität 90% jpg.Compress; with SaveDialog1 do Begin Options:=[ofCreatePrompt,ofEnableSizing,ofHideReadOnly,ofShareAware,ofEnableSizing]; //Ohne Kästchen Filter :='JPG-Dateien (*.jpg)'; filename := ChangeFileExt(filename, '.jpg'); DefaultExt:='jpg'; if execute then Begin jpg.SaveToFile(Filename); End else showmessage('Nicht gespeichert'); End; finally jpg.Free end; end; procedure TForm1.BMPLaden1Click(Sender: TObject);//Menü Begin with openDialog1 do Begin Options:=[ofCreatePrompt,ofEnableSizing,ofHideReadOnly,ofShareAware,ofEnableSizing]; //Ohne Kästchen Filter :='Bitmap-Dateien (*.bmp)'; filename := ChangeFileExt(filename, '.bmp'); DefaultExt:='bmp'; if execute then Begin image1.Picture.LoadfromFile(Filename); End else showmessage('Nicht geladen'); End; end; procedure TForm1.JPEGladen1Click(Sender: TObject); var jpg :TJPEGImage; //benötigt "uses jpeg" begin jpg:=TJPEGImage.Create; try with openDialog1 do Begin Options:=[ofCreatePrompt,ofEnableSizing,ofHideReadOnly,ofShareAware,ofEnableSizing]; //Ohne Kästchen Filter :='JPG-Dateien (*.jpg)'; filename := ChangeFileExt(filename, '.jpg'); DefaultExt:='jpg'; if execute then Begin jpg.loadfromFile(Filename); image1.Picture.Bitmap.assign(jpg); End else showmessage('Nicht gespeichert'); End; finally jpg.Free end; end; procedure TForm1.Beenden1Click(Sender: TObject);//Menü begin close; end; procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);//Ereignis begin EsWirdGezeichnet := true; image1.Canvas.MoveTo(x,y); end; procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); //Ereignis begin if EsWirdGezeichnet then image1.canvas.lineto(x,y); end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); //Ereignis begin EsWirdGezeichnet := false; end;Beispiel Graphik4 Bei bewegten Figuren ist es wichtig die Zeichnung wieder zu löschen. Da geht mit der Canvas-Eigenschaft Pen.Mode = pmNotXor und CopyMode := cmSrcInvert.
procedure zeichneKreis(canv: Tcanvas; x, y, r: integer; farbeRand, farbeInnen:Tcolor); begin with canv do Begin Pen.Style := psSolid; Pen.Mode := pmNotXor; // zweifach zeichnen löscht !!! CopyMode := cmSrcInvert;// zweifach kopieren löscht !!! Pen.Color := farbeRand; Pen.Width := 5; Brush.Style := bssolid; Brush.Color := farbeInnen; Ellipse(x-r,y-r,x+r,y+r) End end; procedure zeichneRechteck(canv: Tcanvas; x1, y1, x2, y2: integer; farbeRand, farbeInnen:Tcolor); const dicke = 50; begin with canv do Begin Pen.Width := dicke; Pen.Color := farbeRand; Brush.Style := bssolid; Brush.Color := farbeInnen; Rectangle (x1 , y1, x2 - dicke, y2 - dicke); End end; procedure TForm1.Button1Click(Sender: TObject); var w, h:integer; begin w := form1.Width; h := form1.Height; with image1 do Begin zeichneRechteck(image1.canvas,0, 0, w, h div 2,clyellow, clblue); zeichneRechteck(image1.canvas,0 , h div 2, w, h, clred, clgreen); End; end; procedure TForm1.Button2Click(Sender: TObject); var w, h:integer; begin w := form1.Width; h := form1.Height; zeichneKreis(image1.canvas, w div 2, h div 2, h div 4, clblack, clred); end;Beispiel Graphik5 Jetzt wollen wir den Kreis noch in Bewegung setzten. Dafür ziehen wir noch den Taktgeber Timer1 von der Systemkomponententabelle auf das Formular. Wir können dann angeben, nach wieviel Millisekunden, der alte Kreis gelöscht und daneben ein neuer Kreis gezeichnet wird. Es sieht dann aus, als würde sich der Kreis bewegen. Die alte Position des Kreises und den Radius merken wir uns in den globen Variablen x0, y0 und r0. (Den Experten wird es grausen, aber es geht auch ohne objektorientierte Programmierung. Die kommt eine Klassenstufe später später.)
var Form1: TForm1; //Schrieb Delphi x0, y0, r0: integer; //Hier die "globen" Variablen! implementation //Schrieb Delphi {$R *.DFM} //Schrieb Delphi procedure zeichneKreis(canv: Tcanvas; x, y, r: integer; farbeRand, farbeInnen:Tcolor); begin with canv do Begin Pen.Style := psSolid; Pen.Mode := pmNotXor; // zweifach zeichnen löscht !!! Pen.Color := farbeRand; CopyMode := cmSrcInvert;// zweifach kopieren löscht !!! Pen.Width := 5; Brush.Style := bssolid; Brush.Color := farbeInnen; Ellipse(x-r,y-r,x+r,y+r); x0 := x; y0 := y; r0 := r; End end; procedure TForm1.Button1Click(Sender: TObject); var w, h:integer; begin w := form1.Width; h := form1.Height; with image1 do Begin //alles löschen Brush.Color := clwhite; canvas.Rectangle(0, 0, w, h); End; end; procedure TForm1.Button2Click(Sender: TObject); var w, h:integer; begin w := form1.Width; h := form1.Height; timer1.Interval := 10; zeichneKreis(image1.canvas, random(w), random(h), 10, clblack, clred); //Zum ersten Mal end; procedure TForm1.Timer1Timer(Sender: TObject); begin zeichneKreis(image1.canvas, x0, y0, r0, clblack, clred); //lösche alten Kreis x0 := x0 + random(100); if x0 <= 0 then x0 := form1.Width; if x0 >= form1.Width then x0 := 0; y0 := y0 + random(10); if y0 <= 0 then y0 := form1.height; if y0 >= form1.height then y0 := 0; zeichneKreis(image1.canvas, x0, y0, r0, clblack, clred); //zeichne neuen Kreis end;Aufgabe Graphik2: Gib dem Kreis eine gewisse Geschwindigkeit. Falls er an den Rand stößt, soll er reflektiert werden. (Einfach die x- oder y-Komponente der Geschwindigkeit invertieren.).
procedure TForm1.Openpicture1Click(Sender: TObject); begin with openpicturedialog1 do Begin Filter := //GraphicFilter(TGraphic); 'Bitmaps (*.bmp)|*.bmp|' + 'Alle (*.*)|*.*'; if execute then image1.Picture.Bitmap.LoadFromFile(filename); //Schon ist das Bild sichtbar end; end; procedure TForm1.BMPSpeichern1Click(Sender: TObject); begin with SaveDialog1 do Begin Filter :='Bitmap-Dateien (*.bmp)'; DefaultExt:='bmp'; if execute then image1.Picture.SaveToFile(Savedialog1.Filename); else showmessage('Nicht gespeichert'); End; end;Beispiel Bild 2 Eine eine JPEG-Grafikdatei laden
procedure Tform1.jpg_laden(datei:string); var jpg :TJPEGImage; //uses jpeg; begin jpg:=TJPEGImage.Create; try jpg.LoadFromFile(datei); image1.Picture.Bitmap.Assign(jpg); with form1 do caption := datei + '('+intToStr(jpg.width) + '*' + intToStr(jpg.height)+')'; finally jpg.Free; end; end;Beim Abspeichern kann man auf Kosten der Schärfe die Komprimierung erhöhen. Im folgenden Beispiel werden mehreren Menüpunkten dasselbe OnClick-Ereignis zugewiesen. (Wenn Du im "Menüeditor" die Caption im Objektinspektor schreibst, dann allen gleichartigen Menüpunkten dieselbe Onclick-Prozedur unter "Ereignisse" zuweisen.)
procedure TForm1.s100Click(Sender: TObject); var jpg :TJPEGImage; begin jpg:=TJPEGImage.Create; try jpg.Assign(image1.Picture.Bitmap); with form1 do caption := intToStr(jpg.width) + '*' + intToStr(jpg.height); if sender = s100 then //das Menü hat den Namen "s100" jpg.CompressionQuality := 100 else if sender = s50 then jpg.CompressionQuality := 50 else if sender = s10 then jpg.CompressionQuality := 10 else if sender = s5 then jpg.CompressionQuality := 5; jpg.Compress; with SaveDialog1 do Begin Filter :='JPG-Dateien (*.jpg)'; DefaultExt:='jpg'; if execute then Begin jpg.SaveToFile(Savedialog1.Filename); End else showmessage('Nicht gespeichert'); End; finally jpg.Free; end; end;Damit ist es auch möglich, BMP-Bilder in JPEG-Graphiken zu komprimieren.
procedure TForm1.Schriftwaehlen1Click(Sender: TObject); begin with fontdialog1 do if execute then image1.Canvas.Font := font; end;Und am besten mit der Maus den Ort angeben, wo die Schrift erscheinen soll.
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var s:string; begin if shift = [ssright] then Begin if InputQuery('Beschriftung', 'Geben Sie den Text ein',s) then image1.Canvas.textout(x,y,s); End; end;
... in das OnClick-Ereignis von Button1: (Auf button1 doppelklicken) procedure TForm1.Button1Click(Sender: TObject); begin panel1.DoubleBuffered := true; //Das muss man halt wissen: Verhindert flackern vx := 1; //Müssen als globale Integervariablen deklariert sein (unter var Form1) vy := 1; timer1.Interval := 10; //Millisekunden end; ... in das timer-Ereignis von Timer1 (Auf button1 doppelklicken) procedure TForm1.Timer1Timer(Sender: TObject); begin shape1.top := shape1.top + vx; shpae1.left := shape1.left + 1; end;Ein Rechteck wandert nach rechts unten ... leider ohne Umkehrung.
x(t) = A(sin(a*t + b)
y(t) = B(sin(c*t + d)
Das Frequenzverhältnis entspricht dabei c : a
die Phasenverschiebung den Parametern d-c
var Form1: TForm1; lissj_t, lissj_a, //Die Konstanten t,a,b,c,d als globale Variablen lissj_b, lissj_c, lissj_d: integer; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin randomize; lissj_t := 0; lissj_a := StrToInt(edit1.text); //Frequenzverhältnis a:c lissj_c := StrToInt(edit2.text); lissj_b := StrToInt(edit3.text); //Phase d - b lissj_d := StrToInt(edit4.text); timer1.Enabled := true; timer1.Interval := 10; end; procedure zeichneKreisAufForm1(x,y:integer); //Kreis mit r = 4Pixel //Im Gegensatz zur Image-Komponente Zeichnung auf Form1 nicht dauerhaft begin with form1.Canvas do Begin Pen.Color := clyellow; //Außen gelb Pen.Width := 2; Brush.Style := bssolid; Brush.Color := clred; //Innen rot Ellipse(x-4,y-4,x+4,y+4) End end; procedure TForm1.Timer1Timer(Sender: TObject); //Alle 10 ms var h,b,p: integer; teiler: real; begin if lissj_t < 900 then inc(lissj_t,3) //3 6 9 12 ... 300 else inc(lissj_t); if lissj_t = 300 then lissj_t := 301; //304 307 ... 601 if lissj_t = 601 then lissj_t := 602; //605 ... 902 //Am Anfang wird mit Lücken gezeichnet. Diese werden dann aufgefüllt. h := form1.height div 4; //Streckunsfaktoren b := form1.Width div 4; p := (lissj_a + lissj_c); teiler := 10/(180*p*sqrt(p)); //Sonst bei großem a+c Sprünge zu gross zeichneKreisaufForm1(2*b + round(b*sin(Pi*(lissj_a*lissj_t + lissj_b)*teiler)), 2*h + round(h*sin(Pi*(lissj_c*lissj_t + lissj_d)*teiler))); end; procedure TForm1.Button3Click(Sender: TObject); //Canvas löschen begin lissj_t := 0; with form1.Canvas do Begin Brush.Color := claqua; Rectangle(0,0,form1.Width,form1.Height) End; Button1Click(nil); end; procedure TForm1.Button2Click(Sender: TObject); begin close end;Aufgabe timer2 Schreibe ein Programm, bei dem eine roter Kreis über einer Ebene (=Strich) schwebend hinabrollt.
Betrifft eine Frage aus der FAQ.
Nun ein Beispiel, wie ein Array als Rückgabewert einer Funktion verwendet werden kann.unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; const Anzahl =10; Hoehe =35; type Tmyarray= array of TImage; type TForm1 = class(TForm) Timer1: TTimer; Button1: TButton; Label1: TLabel; Label2: TLabel; procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); private arraymitautos: Tmyarray; zweiterstart: boolean; {Private-Deklarationen } public {Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} function gibmirarray: Tmyarray; var i:integer; begin setlength(result,Anzahl); for i:= 0 to Anzahl-1 do Begin result[i]:= Timage.create(Form1); //Damit Freigabe bei Form1.destroy result[i].parent := form1; result[i].picture.loadfromfile('laeuffer.bmp'); //Oder: Case i mod 3 = 0 of 0: result[i].picture.loadfromfile('Auto0.bmp'); // ... result[i].height:= hoehe; result[i].left:= 0; result[i].top := (hoehe+5)*(i+2); {Falls 'lauffer.bmp' nicht vorhanden result[i].Canvas.Brush.Color := RGB(255,random(256),255); result[i].width:= hoehe; result[i].height:= hoehe; result[i].left:= 0; result[i].top := (hoehe+5)*(i+2); result[i].Canvas.Ellipse(0,0,hoehe,hoehe); result[i].Canvas.TextOut(0,0,intToStr(i+1)); Ende of "vereinfacht"} End; End; procedure zerstoereArray(x: Tmyarray); var i: integer; begin for i := 0 to length(x) - 1 do x[i].free; setlength(x,0); end; procedure TForm1.Timer1Timer(Sender: TObject); //Vorwärts gehts! var i:integer; begin for i := 0 to Anzahl-1 do Begin if i mod 2 = 0 then arraymitautos[i].Left := arraymitautos[i].Left + random(5)+1 else if zweiterStart then arraymitautos[i].Left := arraymitautos[i].Left + random(10)+1; if arraymitautos[i].Left > form1.Width - 3*Hoehe then Begin timer1.Interval := 0; label2.Caption := 'Gewonnen hat Nr.' + IntToStr(i+1); End; End; if arraymitautos[0].Left > form1.width div 2 - 5*Hoehe then zweiterstart := true; end; procedure TForm1.Button1Click(Sender: TObject);//Je nach Caption begin if button1.Caption = 'Neu' then Begin zerstoereArray(arraymitautos); button1.Caption := 'Start'; timer1.Enabled := false; exit; End; randomize; //Unwichtig! form1.top := 0; form1.left := 0; form1.Width := screen.Width; form1.Height := (Hoehe + 5)*(Anzahl + 4); //Ende "unwichtig" //timer1.enabled := false; Im Objektinspektor arraymitautos := gibmirarray; //Ein Wettrennen wird gestartet timer1.enabled := true; timer1.Interval := 100; zweiterStart := false; //Rest des Wettrennens siehe Procedure Timer1Timer button1.Caption := 'Neu'; //Zweiter Start erst nach free label2.Caption := ''; end; end.Downloadseite "Wettrennenpas.zip"
program DPR_Datei_Genuegt; //Der Name soll sagen: Die Projektdatei genügt. uses Classes, Forms, Sysutils, StdCtrls; type TMyForm = class(TForm) //Myform wird vererbt von TForm mybOk: Tbutton; //... wird nun eine Eigenschaft von TMyform mybSchliessen: TButton; // " myLHalloWelt: TLabel; // " mySList: Tstringlist; // " procedure BOkClick(Sender: TObject); // wird nun eine Methode von TMyform // und wird noch implementiert. procedure BSchliessenClick(Sender: TObject); // " public Constructor Create(aOwner: TComponent); override; //Create und Destroy sind die wichtigsten Methoden //einer Klasse (hier werden sie "überschrieben", Destructor Destroy; override; //Wenn der Speicher aufgeräumt werden soll. end; //Implementierung der Methoden Constructor TMyForm.Create(aOwner: TComponent); begin inherited CreateNew(aOwner); //vor dem "überschreiben" wird alles von TForm übernommen. //Darum brauchst Du dich nicht zu kümmern. mybok := TButton.Create(self); //Wird erst zur Laufzeit erzeugt //Wird mit Instanz von TMyform freigegeben (.free) mybok.Parent := self; //Ganz wichtig !!! Wohin soll der Button! mybok.Caption := 'Ok'; mybok.OnClick := self.BOkClick; mybschliessen := TButton.Create(self); mybschliessen.Parent := self; mybschliessen.Caption := 'Schließen'; mybschliessen.Top := mybok.Height; mybschliessen.OnClick := self.BSchliessenClick; myLHalloWelt := TLabel.Create(self); mySList := Tstringlist.create; // Ohne Owner. Dafür free notwendig mySList.add('Hallo Welt!'); mySList.Add('Gibts was Neues?'); myLHalloWelt.Parent := self; myLHalloWelt.Top := 100; myLHalloWelt.left := 100; end; Destructor TMyForm.Destroy; begin MySList.Free; //Speicher aufräumen! // MySList hat keinen Eigentümer, der dies tut. inherited Destroy end; procedure TMyForm.BOKClick(Sender: TObject); var formb: TMyform; begin myLHalloWelt.Caption := MySList.Text; formb:= TMyForm.Create(self); formb.Caption := 'Weitere Instanz'; //lauter neue Instanzen werden erzeugt formb.Top := random(550); formb.Left := random(750); formb.Show; end; procedure TMyForm.BSchliessenClick(Sender: TObject); begin close; end; //Beginn des Programms var forma: TMyForm; begin //Hier beginnt das Programm application.Initialize; //Die erste Instanz wird mit application erzeugt //einfach abschreiben (muß für OOP nicht verstanden werden) randomize; Application.CreateForm(TMyForm, Forma); forma.Caption := 'Hauptform'; Application.Run; end.Aufgabe: Schreibe in dieser Form ein Programm mit drei Eingabeeditfenstern und zwei Ausgabeeditfenstern, das nach Eingabe von a,b,c die Lösung der Gleichung ax^2+bx+c=0 ausgibt.