| Autor |
Beitrag |
DarthBane9955
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 18.11.11 14:24
Hallo,
wir sind in der Schule dabei ein Programm zu schreiben, bei dem beim Klicken eines Buttons ein Fenster aufgeht und dann ein Haus mit Canvas gezeichnet wird und eine Sonne (Unterklasse TSonne von TShape) angezeigt wird. Desweiteren gibt es die Funktionen TuerAuf/Zu wobei aber zur Vereinfachung nur die Farbe gewechselt wird und die Funktion LichtAn/Aus.
Leider wird das Haus nicht gezeichnet, drücke ich aber auf die Buttons von Tür und Licht werden Fenster und Tür gezeichnet (  ).
Ich hoffe ihr könnt mir eine schnelle Problemhilfe geben.
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: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288:
| mHaus (Main): unit mHaus;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, mGebaeude, mSonne, mZeichenfenster;
type TMain = class(TForm) BtHaus: TButton; BtLichtAnAus: TButton; BtTuerAufZu: TButton; procedure BtHausClick(Sender: TObject); procedure BtLichtAnAusClick(Sender: TObject); procedure BtTuerAufZuClick(Sender: TObject);
private ZF: TZeichenFenster; Haus : THaus; Sonne: TSonne; public
end;
var Main: TMain;
implementation
{$R *.dfm}
procedure TMain.BtHausClick(Sender: TObject); begin ZF := TZeichenFenster.Create (Main); ZF.Show;
Haus := THaus.Create(ZF,50,300,100); Haus.Zeichnen;
Sonne := TSonne.Create (ZF); Sonne.Parent := ZF; Sonne.Show;
end;
procedure TMain.BtLichtAnAusClick(Sender: TObject); begin if Haus.IstLichtAn = False then Haus.LichtAn else Haus.LichtAus; end;
procedure TMain.BtTuerAufZuClick(Sender: TObject); begin if Haus.IstTuerAuf = False then Haus.TuerAuf else Haus.TuerZu; end;
end.
mSonne:
unit mSonne;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TSonne = class (TShape)
private
protected
public constructor Create (AOwner: TComponent); override;
end;
implementation
constructor TSonne.Create (AOwner: TComponent); begin inherited Create (AOwner); Brush.Color := clYellow; SetBounds (185,60,66,66); Shape := stCircle; end;
end.
mZeichenFenster
unit mZeichenFenster;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TZeichenFenster = class(TForm) private
public Constructor Create (AOwner: TComponent); override; end;
var ZeichenFenster: TZeichenFenster;
implementation
{$R *.dfm}
Constructor TZeichenFenster.Create (AOwner: TComponent); begin inherited Create (Aowner); Brush.Color := clWhite; SetBounds (550, 121, 340, 340); end;
end.
mGebaeude (Haus deklariert)
unit mGebaeude;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, mZeichenFenster;
type THaus = class(TObject) private zX,zY,zBreite : Integer; zLichtAn, zTuerAuf : Boolean; kZF: TZeichenFenster;
protected procedure WandZeichnen; procedure TuerZeichnen( Farbe : TColor); procedure FensterZeichnen( Farbe : TColor); procedure DachZeichnen;
public constructor Create(ZF: TZeichenFenster; X, Y, Breite : Integer); procedure Zeichnen; procedure LichtAn; procedure LichtAus; procedure TuerAuf; procedure TuerZu; function IstTuerAuf : Boolean; function IstLichtAn : Boolean;
end;
implementation
constructor THaus.Create(ZF: TZeichenfenster; X, Y, Breite : Integer); begin zX := X; zY := Y; zBreite := Breite; zLichtAn := False; zTuerAuf := False; kZF := ZF end;
procedure THaus.Zeichnen; begin kZF.Canvas.Pen.Color := clBlack; WandZeichnen; DachZeichnen; FensterZeichnen(cl3DDkShadow); TuerZeichnen(clRed); end;
procedure THaus.WandZeichnen; begin kZF.Canvas.Brush.Color := clGray; kZF.Canvas.Rectangle(zX, round (zY - zBreite), round (zX + zBreite), zY); end;
procedure THaus.TuerZeichnen(Farbe : TColor); begin kZF.Canvas.Brush.Color := Farbe; kZF.Canvas.Rectangle(round (zX + zBreite * 0.2), round (zY - zBreite * 0.4), round(zX + zBreite * 0.4), zY); end;
procedure THaus.FensterZeichnen(Farbe : TColor); begin kZF.Canvas.Brush.Color := Farbe; kZF.Canvas.Rectangle (round (zX + zBreite * 0.6), round (zY - zBreite * 0.4), round (zX + zBreite * 0.8), round (zY - zBreite * 0.2)); kZF.Canvas.Rectangle (round (zX + zBreite * 0.2), round (zY - zBreite * 0.8), round (zX + zBreite * 0.4), round (zY - zBreite * 0.6)); kZF.Canvas.Rectangle (round (zX + zBreite * 0.6), round (zY - zBreite * 0.8), round (zX + zBreite * 0.8), round (zY - zBreite * 0.6)); end;
procedure THaus.DachZeichnen; begin kZF.Canvas.Brush.Color := clRed; kZF.Canvas.Polygon([Point (zX, round (zY - zBreite)), Point (round (zX + zBreite - 1), round (zY - zBreite)), Point (round (zX + zBreite * 0.5), round (zY - zBreite * 1.3))]); end;
procedure THaus.LichtAn; begin FensterZeichnen(clYellow); zLichtAn := True; end;
procedure THaus.LichtAus; begin FensterZeichnen(cl3DDkShadow); zLichtAn := False; end;
procedure THaus.TuerAuf; begin TuerZeichnen(cl3DDkShadow); zTuerAuf := True end;
procedure THaus.TuerZu; begin TuerZeichnen(clRed); zTuerAuf := False; end;
function THaus.IstTuerAuf : Boolean; begin IstTuerAuf := zTuerAuf; end;
function THaus.IstLichtAn : Boolean; begin IstLichtAn := zLichtAn; end;
end. |
PS: Bitte nicht hinterfragen, warum ich etwas so ausgedrückt habe das ist alles Anweisung vom Lehrer. Verwendete Version: Delphi 7
All Smiley bedeuten 8 ) ohne space
Moderiert von Gausi: Delphi-Tags hinzugefügt
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 18.11.11 15:04
ich enthalte mich mal jeden Kommentars ...
in Festerzeichnen gab es eine paar Klammerprobleme in der Art wie Du den Code hochgelegt hast
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TMain.BtHausClick(Sender: TObject); begin if not Assigned(ZF) then ZF := TZeichenFenster.Create (Main);ZF.Show; Application.ProcessMessages;
procedure THaus.LichtAn; begin FensterZeichnen(clYellow); zLichtAn := True; end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
patmann2001
      
Beiträge: 201
Windows 7 Prof.
Delphi XE2
|
Verfasst: Fr 18.11.11 15:36
Hallo,
neben den Klammerproblemen solltest Du keinesfalls eine Form in einer Form Createn, sondern im Hauptprogramm mit Application.CreateForm(TZeichenFenster, ZeichenFenster);
Ausserdem, wenn du das Shape auskommentierst, taucht dein Haus auf. Nimmst du das Shape mit rein, ist es weg. Sind da vielleicht die Dimensionen nicht richtig?
lg Patmann
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 18.11.11 16:16
patmann2001 hat folgendes geschrieben : | | neben den Klammerproblemen solltest Du keinesfalls eine Form in einer Form Createn, sondern im Hauptprogramm mit Application.CreateForm(TZeichenFenster, ZeichenFenster); |
Da würde mich aber mal deine Begründung interessieren...
|
|
patmann2001
      
Beiträge: 201
Windows 7 Prof.
Delphi XE2
|
Verfasst: Fr 18.11.11 16:29
Siehe Delphi Hilfe.
| Zitat: |
CreateForm erzeugt das Applet-Objekt bzw. die Applet-Objekte für die Applet-Anwendung.
procedure CreateForm(InstanceClass: TComponentClass; var Reference); virtual;
Beschreibung
Rufen Sie CreateForm nicht in einer Anwendung auf. Der Modul-Manager von Delphi ruft CreateForm intern auf, um die Applet-Objekte mit der Applet-Anwendung zu registrieren.
CreateForm instantiiert für jedes in der Applet-Anwendung enthaltenes Applet ein TApplet-Objekt. Die Komponente wird bei Erzeugung der Applet-Anwendung für das erste Applet-Modul automatisch aufgerufen. Danach wird CreateForm für jedes neu zur Applet-Anwendung hinzugefügte Applet-Modul aufgerufen. Wenn Sie ein neues Applet-Modul hinzufügen wollen, wählen Sie im IDE-Hauptfenster im Menü den Befehl Datei / Neu / Weitere und im Dialogfeld Objektgalerie das Symbol Applet-Modul.
|
| Zitat: |
Die Methode Create erzeugt und initialisiert ein neues TForm-Objekt.
constructor Create(AOwner: TComponent); override;
Beschreibung
Mit Create können Sie ein neues Objekt der Klasse TForm oder einer abgeleiteten Klasse von TForm zur Laufzeit instantiieren. Der Parameter AOwner gibt den Eigentümer des Objekts an.
Verwenden Sie für Nachkommen von TCustomForm, die keine TForm-Objekte darstellen, stattdessen die Methode CreateNew. Wenn Sie Create für Nachkommen von TCustomForm, die keine TForm-Objekte sind, aufrufen, wird eine Exception ausgelöst. |
Man kann natürlich auch TForm.Create aufrufen, wenn man sich gerne zusätzlich arbeit macht. Soll ja Menschen geben, die gerne auf die Unterstützung der Entwicklungsumgebung verzichten.
Aber ich denke, das ganze führt hier am Thema vorbei.
Lg Patmann
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 18.11.11 17:04
@patman
Du hast schon gesehen wo Du das gefunden hast? (TAppletApplication)
und, bei unseren Anwendungen werden üblicherweise neben dem Mainform und einem Datemodul gegf. eine Reportingmodul keine (der oft bis zu 200) Forms automatisch erzeugt.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
jaenicke
      
Beiträge: 19339
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 18.11.11 17:14
bummi hat folgendes geschrieben : | | und, bei unseren Anwendungen werden üblicherweise neben dem Mainform und einem Datemodul gegf. eine Reportingmodul keine (der oft bis zu 200) Forms automatisch erzeugt. |
Bei uns auch. Unter anderem aus Geschwindigkeitsgründen. Aber auch weil es wenig sinnvoll ist in den Speicher Sachen zu laden, die gar nicht gebraucht werden.
Außerdem können Formulare bei uns teilweise auch mehrfach geöffnet werden und werden dann automatisch entsprechend nummeriert etc., was bei der automatischen Erzeugung natürlich nicht ginge.
Dazu kann man Formulare, wenn man sie selbst explizit erzeugt auch genau dann explizit freigeben, wenn sie nicht mehr braucht.
Und so weiter...
|
|
Blup
      
Beiträge: 176
Erhaltene Danke: 44
|
Verfasst: Fr 18.11.11 17:48
Delphi-Quelltext 1: 2:
| TSonne = class (TShape) THaus = class (TObject) |
Tatsächlich wird dein Haus durch deine Anweisungen vermutlich gezeichnet, allerdings wird danach die Sonne auf das Formular gelegt. Das Formular löscht daraufhin seinen Inhalt mit der Hintergrundfarbe und fordert alle Steuerelemente zum Zeichnen auf.
Die Sonne ist von einer Klasse abgeleitet, die sich beim Hintergrund (in dem Fall das Formular) registiert und nach dessen Anforderung automatisch neu zeichnet.
Das Haus kann das schon auf Grund seiner Abstammung nicht.
Im Prinzip müsste THaus etwa so deklariert werden:
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: 76: 77: 78:
| THaus = class(TGraphicControl) private FTuerAuf : Boolean; FLichtAn : Boolean; procedure SetTuerAuf(AValue: Boolean); procedure SetLichtAn(AValue: Boolean); procedure Zeichnen; procedure DachZeichnen; procedure WandZeichnen; procedure TuerZeichnen; procedure FensterZeichnen; public procedure Paint; override; property IstTuerAuf : Boolean read FTuerAuf write SetTuerAuf; property IstLichtAn : Boolean read FLichtAn write SetLichtAn; end;
procedure THaus.SetTuerAuf(AValue: Boolean); begin FTuerAuf := AValue; TuerZeichnen; end;
procedure THaus.SetLichtAn(AValue: Boolean); begin FLichtAn:= AValue; FensterZeichnen; end;
procedure THaus.Paint; begin Zeichnen; end;
procedure THaus.Zeichnen; begin WandZeichnen; DachZeichnen; FensterZeichnen; TuerZeichnen; end;
procedure THaus.WandZeichnen; begin Canvas.Brush.Color := clGray; Canvas.Pen.Color := clBlack; Canvas.Rectangle( ); end;
procedure THaus.TuerZeichnen; begin if FTuerAuf then Canvas.Brush.Color := cl3DDkShadow else Canvas.Brush.Color := clRed; Canvas.Pen.Color := clBlack; Canvas.Rectangle( ); end;
procedure THaus.FensterZeichnen; begin if FLichtAn then Canvas.Brush.Color := clYellow else Canvas.Brush.Color := cl3DDkShadow; Canvas.Pen.Color := clBlack; Canvas.Rectangle( ); Canvas.Rectangle( ); Canvas.Rectangle( ); end;
procedure THaus.DachZeichnen; begin Canvas.Brush.Color := clRed; Canvas.Pen.Color := clBlack; Canvas.Polygon( ); end; |
Zu beachten ist, alle Zeichenoperationen müssen innerhalb des Rechtecks (0, 0, width, height) des jeweiligen Steuerelement vorgenommen werden. Also entsprechend groß machen, damit auch das Dach reinpasst. Die Position auf dem übergeordneten Steuerelement (dem Formular) muss man dabei überhaupt nicht berücksichtigen.
|
|
DarthBane9955
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 18.11.11 22:20
// das kann auch nicht so gedacht sein
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure THaus.LichtAn; begin FensterZeichnen(clYellow); zLichtAn := True; end; |
Wie meinen?!
Tatsächlich wird dein Haus durch deine Anweisungen vermutlich gezeichnet, allerdings wird danach die Sonne auf das Formular gelegt. Das Formular löscht daraufhin seinen Inhalt mit der Hintergrundfarbe und fordert alle Steuerelemente zum Zeichnen auf.
Die Sonne ist von einer Klasse abgeleitet, die sich beim Hintergrund (in dem Fall das Formular) registiert und nach dessen Anforderung automatisch neu zeichnet.
Das Haus kann das schon auf Grund seiner Abstammung nicht.
reicht nicht einfach das aufrufen von beiden umzukehren?
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 18.11.11 22:37
Der ganze Ansatz ist völlig krank (deshalb meinte ich mich ich enthalte mich eines Kommentars), abgesehen davon dass hier Zeichenroutinen mit Komponenten gemischt werden...
Entweder man versorgt die Zeicheklassen mit allen Informationen sich komplett neu malen zu können und ruft bei Bedarf eine Routine "MalAllesNeu", üblicherweise heißt diese Paint, auf, hier macht es dann auch nichts wenn das Teil sich selbst neu malen möchte, z.B. weil es zwischendurch verdeckt wurde
oder man verwendet ein Persistentes Canvas wie z.B. TImage welches intern in eine Bitmap malt und diese im Paint darstellt.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
DarthBane9955
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 18.11.11 23:18
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Die sind alles Vorgaben unseres Lehrers-.-
Non-Sense aber zu beachten
|
|
|