Autor Beitrag
DarthBane9955
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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:
ausblenden volle Höhe Delphi-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 (550121340340);
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 user profile iconGausi: Delphi-Tags hinzugefügt
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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

ausblenden 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);// nicht neu erzeugen wenn schon erzeugt
ZF.Show;
Application.ProcessMessages; // sonnst malst Du vor das Fenster sichtbar ist, beim Show malt es sich selbst mit "nichts"


// das kann auch nicht so gedacht sein

procedure THaus.LichtAn;
begin
FensterZeichnen(clYellow);
zLichtAn := True;
end;

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
patmann2001
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 201

Windows 7 Prof.
Delphi XE2
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 18.11.11 16:16 
user profile iconpatmann2001 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 201

Windows 7 Prof.
Delphi XE2
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 18.11.11 17:14 
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 176
Erhaltene Danke: 44



BeitragVerfasst: Fr 18.11.11 17:48 
ausblenden 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:
ausblenden volle Höhe Delphi-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:
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
  {auf Anforderung automatisch neu zeichnen}
  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



BeitragVerfasst: Fr 18.11.11 22:20 
// das kann auch nicht so gedacht sein
ausblenden 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 user profile iconNarses: Delphi-Tags hinzugefügt
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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



BeitragVerfasst: Fr 18.11.11 23:18 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Die sind alles Vorgaben unseres Lehrers-.-
Non-Sense aber zu beachten