Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Ein Panel an eine Instanz einer Klasse TBall übergeben (https://www.delphipraxis.net/210154-ein-panel-eine-instanz-einer-klasse-tball-uebergeben.html)

Smiley 9. Mär 2022 16:29

Delphi-Version: 10.4 Sydney

Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Liste der Anhänge anzeigen (Anzahl: 7)
Hallo Delphi Freunde
ich habe eine Klasse TBall erstellt, die soll einen Ball auf einem übergebenen TPanel fliegen lassen.
Das Aufrufende Form mit dem Panel1 soll eine Instanz von TBall erstellen und das Panel an die Klasse TBall übergeben.
In TBall erzeuge ich einen Timer der den Ball fliegen lässt (Kreis prallt an den Rändern ab).

1. Ich habe versucht das Panel als Property zu übergeben (BallA:=TBall.Create; BallA.Panel:=Panel1; BallA.Start)
über BallA.Start soll sich der Ball in dem Panel bewegen.
Es ist aber nicht im Panel zu sehen.
Wie würdet ihr das übergeben des Panels machen, kann ich das "übergeben" eventuell auch mit dem Create machen? (BallA:=TBall.Create(Panel1)
Das hat, bei mir, in dieser Syntax so nicht funktioniert.

2. Geht das überhaupt, dass der Timer den ich in der Klasse Ball erzeuge unabhängig läuft und ich mit jeder erzeugten Instanz von TBall ein eigenes Intervall im Timer setzen kann?
Sollte doch funktionieren.
Ich habe jedoch gelesen, dass das Timer-Objekt nicht Threadsave ist, somit kann ich die Erzeugten Bälle dann wohl nicht in einen eigenen Thread auslagern, nehme ich an.
Oder gibt es dafür eine Lösung?

3. Im Constructor Create funktioniert keinen Haltepunkt. Erst wenn ich die Initialisierung meiner Variablen in eine procedure Init auslagere und diese aufrufe, dann bleibt das Prgramm beim Haltepunkt im Init stehen. Ist das so normal?

stahli 9. Mär 2022 18:02

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Aus Zeitgründen habe ich jetzt nicht Deinen Quellcode eingesehen.

1) Grundsätzlich musst Du einem zur Laufzeit erzeiugten Control aber auch noch einen Parent zuweisen.
Delphi-Quellcode:
MyBall.Parent := MyPanel;
Damit sollte Dein Control zumindest schon mal sichtbar sein.

2) Die VCL ist für Spiele und Echtzeitanwendungen eher ungeeignet.
Du kannst zwar einen Timer verwenden und so einzelne Schritte von Objekte berechnen während Du auch noch auf Maus und Tastatur reagierst, aber das ist eher nur für Testzecke und zum Lernen tauglich.
Irgendwann wird das hakelig und umständlich.
Aber zum Lernen ist das erst mal völlig in Ordnung. Threads zu verwenden ist aufwendig und eher für umfangreichere (längere) Positionsberechnungen die Ergebnisse dann innerhalb der VCL darzustellen muss wieder synchronisiert werden. Das heißt, man muss genau überlegen, was man wie und warum in einen Thread auslagert.
Wir hatten hier https://www.delphipraxis.net/175033-...-schlecht.html mal ein paar Überlegungen zu dem Themenbereich angestellt und bei #59 habe ich mal ein kleines Testprojekt vorgestellt.

3) Ein Haltepunkt sollte auch im Constructor funktionieren. Vermutlich wird der bei Dir nicht korrekt aufgerufen.

Smiley 9. Mär 2022 18:17

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Danke Stahli für Deine Antwort.

Das zuweisen des Balls habe ich mit:
shpBall := TShape.create(fSpielfeld);
shpBall.Left := 10;
shpBall.Top := 10;
shpBall.Pen.Color := fPenColor;
shpBall.Brush.Color := fBrushColor;
shpBall.SetParentComponent(fSpielfeld); <---

gemacht.
Das scheint aber nicht korrekt zu sein.

Mein Contructor von TBall sieht so aus:
constructor Tball.Create;
begin
Init;
end;
Wenn ich einen Haltepunkt auf das Init setze, bleibt der Debugger da nicht stehen.
Als würde der Constructor gar nicht aufgerufen.
Sollte er aber doch bei TBall.Create oder?

Smiley 9. Mär 2022 18:34

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Mir fällt gerade auf, ich sollte dem Shape auch sagen welche Form es annehmen soll.:wall:

Blup 10. Mär 2022 07:30

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Zitat von Smiley (Beitrag 1503095)
Das zuweisen des Balls habe ich mit:
shpBall := TShape.create(fSpielfeld);

Das scheint aber nicht korrekt zu sein.

Mein Contructor von TBall sieht so aus:
constructor Tball.Create;

Du rufst den richtigen virtuellen constructor von TComponent auf, deklarierst aber einen anderen, der aber nicht aufgerufen wird.
Deine Deklaration müsste eigentlich so aussehen:
Delphi-Quellcode:
type
  TBall = class({...})
  public
    constructor Create(AOwner: TComponent); override;
  {...}
Und nicht das "inherited;" als erste Zeile im constructor vergessen.

venice2 10. Mär 2022 08:19

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Vielleicht kannst du dir hier etwas von abschauen..
..gelöscht!

Smiley 10. Mär 2022 11:06

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
@Venice2
Dein Strandball ist toll, aber zu kompliziert für ein Tutorial, wegen der vielen Windows und OpenGL Aufrufe.
Du hast im Main zuviel von den OpenGL Aufrufen drin, das verwirrt mich.
Das Global.pas ist schön aufgeräumt und mit normalem DelphiCode, das hätte ich in das Main.pas mit reingenommen und das aus dem Main.pas ausgelagert.
Ich versuche im Main.pas nur das nötigste reinzuschreiben, um einen Überblick zu haben.
Soviel zu meiner Meinung zu Deinem SourceCode.

Jetzt zu meinem eigentlichen Problem:
Im TBall möchte ich beim erstellen eine InitRoutine aufrufen, daher dachte ich mir ich benutze den Contructor, der sollte doch aufgerufen werden, wenn das Object angelegt wird.
(Ball:=TBall.Create)
Weiterhin ist die Überlegung von welchem Typ ich mein TBall anlegen sollt.
TObject oder TComponent oder ???
Wie deklariere ich den Constructor und wie implementiere ich ihn dann.
Benutze ich override oder virtual oder ???
Im Init create erstelle ich auch einen Timer den ich verwende.
Den muss ich doch später wieder freigeben.
Dafür dachte ich, verwende ich doch den destructor.

1. Hier ist also einmal die Frage von welchen Typ sollte ich am besten ableiten.
2. Wie sieht die Syntax für den Constructor und Destructor aus (in der Deklaration und der Implemetation)
3. Geht es auch anders, dass ich eine Init Routine beim Create aufrufen kann ohne einen Constructor anzulegen?

Das ganze ist für mich der Einstieg in die OOP und die Erstellung von Objekten.
Der Ball ist nur ein Beispiel für das Aufrufen eines Objektes und das arbeiten auf Objekten des Aufrufenden.
Danach versuche ich mehrere Möglichkeiten den Ball darzustellen (Mit Draw,als Shape, als Image oder als letztes mit OpenGL)

venice2 10. Mär 2022 15:42

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

@Venice2
Dein Strandball ist toll, aber zu kompliziert für ein Tutorial, wegen der vielen Windows und OpenGL Aufrufe.
Na dann.. kein OpenGL

Smiley 10. Mär 2022 16:20

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
@Venice2
Sehr schön gemacht, sieht auch gut aus ohne das OpenGL.
Du hast hier SKAERO verwendet, ist das etwas zusätzliches, konnte auf die schnelle nichts dazu finden.
Viel WindowsCode(Fensterverwaltung mit drin) und einiges das aussieht als sei es zu einer Zeit geschrieben als Delphi noch nicht so viel mit drin hatte (StrUtils gibts mittlerweile für MidStr,LeftStr usw., hatte ich mir früher auch mal selbst gebastelt aus dem Copy Befehl).
Globals.pas ist scheinbar eine alte Zusammenstellung von Befehlen, um es mit einigen Befehlen leichter zu haben. (Einiges gibt es jetzt schon in Delphi).

Die Sprite Technik ist was für mich, das scheint etwas einfacher zu sein als OpenGL.

Danke für den Code, da kann ich noch einiges draus lernen.

venice2 10. Mär 2022 17:01

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Zitat von Smiley (Beitrag 1503132)
@Venice2
Sehr schön gemacht, sieht auch gut aus ohne das OpenGL.
Du hast hier SKAERO verwendet, ist das etwas zusätzliches, konnte auf die schnelle nichts dazu finden.
Viel WindowsCode(Fensterverwaltung mit drin) und einiges das aussieht als sei es zu einer Zeit geschrieben als Delphi noch nicht so viel mit drin hatte (StrUtils gibts mittlerweile für MidStr,LeftStr usw., hatte ich mir früher auch mal selbst gebastelt aus dem Copy Befehl).
Globals.pas ist scheinbar eine alte Zusammenstellung von Befehlen, um es mit einigen Befehlen leichter zu haben. (Einiges gibt es jetzt schon in Delphi).

Die Sprite Technik ist was für mich, das scheint etwas einfacher zu sein als OpenGL.

Danke für den Code, da kann ich noch einiges draus lernen.

Es geht hier eben darum keine VCL zu verwenden und einige Funktionen bzw. Units auszusparen das ist der ganze Trick!
SKAERO ist eine von mit erstellte Engine mit der man unabhängig von der VCL ist. Inclusive Skin Support und Verwendungen von Sprites.
Diese kann man mit der Maus selektieren und verschieben solange wie sie bei der Erstellung nicht gesperrt werden.
Der Cursor ändert sich dann zum Kreuz.

Hier ein Update damit kannst du anschließend den Ball (Sprite(0..3)) zur Laufzeit auf eine andere Position verschieben.
Auch der Lauftext ist ein Sprite und kann verschoben werden.

Einfach diese Funktion ersetzen.
Delphi-Quellcode:
{$REGION 'DrawBounce'}
procedure DrawBounce;
var
  K: Integer;
  x, y: Integer;
  s: PSpriteData;
  rc: TRect;
begin

  if bAnimate then
  begin
    GetClientRect(HSprCtrl, rc);

    for K := 3 downto 0 do
    begin
      // wenn der linke Button gedrückt wird und die Maus sich auf einem Sprite (Ball(0..3))
      // befindet kann man ihn verschieben von dieser Position aus bewegt er sich dann weiter.
      if not gSprCtrl.GI_IsLButtonDown then
      begin
        s := @gSpriteData[k];
        if s.xDir > 0 then
        begin
          if s.xPos + s.nWidth > rc.Right then
            s.xDir := -s.xDir;
        end else
        if s.xPos < 0 then
          s.xDir := -s.xDir;

        if s.yDir > 0 then
        begin
          if s.yPos + s.nHeight > rc.Bottom then
            s.yDir := -s.yDir;
        end else
        if s.yPos < 0 then
          s.yDir := -s.yDir;

        s.xPos := s.xPos + s.xDir;
        s.yPos := s.yPos + s.yDir;
        gSprCtrl.GD_SetObjectXY(s.ID, s.xPos, s.yPos);
      end else
      begin
        s := @gSpriteData[k];
        // x, y Position vom aktuell selektierten Sprite
        // abhängig von der dazu gehörigen ID einlesen.
        gSprCtrl.GD_GetObjectXY(s.ID, x, y);
        s.xPos := x;
        s.yPos := y;
        // neue Position setzen
        gSprCtrl.GD_SetObjectXY(s.ID, s.xPos, s.yPos);
      end;
    end;

    if UseMarquee then
    begin
      gSprCtrl.GD_GetObjectXY(ID_OBJECT_MARQUEE, x, y);

      x := x - 2;
      if x < -MarqueeWidth then
        x := rc.Right + MarqueeWidth;
      gSprCtrl.GD_SetObjectXY(ID_OBJECT_MARQUEE, x, y);
    end;

    gSprCtrl.GI_UpdateWindow(HSprCtrl, false);
  end;
end;
{$ENDREGION}
uControls..
Delphi-Quellcode:
  for K := 0 to ID_MAX_SPRITE - 1 do
  begin
    gSpriteData[K].hBmp   := gSprCtrl.GI_CreateBitmapFromFile(PWideChar(gSpriteData[K].ImageName), ImgW, ImgH);
    gSpriteData[K].ID     := ID_OBJECT_SPRITE + K;
    gSpriteData[K].nWidth := ImgW;
    gSpriteData[K].nHeight := ImgH;
    gSpriteData[K].xPos   := random(400);
    gSpriteData[K].yPos   := random(300);

    gSprCtrl.GD_DrawBitmapToCtrl(HSprCtrl, gSpriteData[K].xPos, gSpriteData[K].yPos, gSpriteData[K].hBmp, $FFFFFFFF,
      gSpriteData[K].ID, GS_VISIBLE);
    // Werden die Sprites gesperrt lassen sie sich nicht mehr verschieben.
    gSprCtrl.GD_SetObjectLocked(gSpriteData[K].ID, true);
  end;

Smiley 11. Mär 2022 11:30

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
@Venice2
Danke für Deine Hilfe Venice2

Das mit den $Region´s kannte ich noch gar nicht.
Tolles Feature um den Quelltext lesbarer (zusammmenklappbar über mehrere Proceduren) zu machen.


Die procedure InitPath verwirrt mich etwas. Die beiden If/else Zweige führen den gleichen Befehl aus, habe ich da etwas übersehen ?
Möglicherweise ein Überbleibsel aus einer Zeit als TiniFile.Create noch nicht automatisch die Ini-Datei angelegt hat?
Code:
procedure InitPath;
begin
  UserAppDataDir := GetSpecialFolder(CSIDL_APPDATA);
  if FileExists(UserAppDataDir +  '\BrewIdeas\Bounce' + '\Bounce.ini') then
    BounceIni := TIniFile.Create(UserAppDataDir + '\BrewIdeas\Bounce' + '\Bounce.ini')
  else
    BounceIni := TIniFile.Create(UserAppDataDir + '\BrewIdeas\Bounce' + '\Bounce.ini');
end;
Hast Du irgend eine Art von Dokumentation zu den wichtigsten Befehle der SKAeroAPI.
Der SourceCode ist schon gut Dokumentiert.
Sonst schreib ich mir dazu etwas um leichter die API verwenden und erklären zu können.
Das verwende ich dann für die Stufe 2 des Ball Projektes für meine Praktikanten.

Das Projekt lässt sich nicht compilieren, da er die Unit Graphics nicht findet, da du da scheinbar deine eigene Graphics.pas benutzt hast um die VCL zu umgehen, nehme ich an.
Was muss dafür noch eingestellt werden im Compiler?
Ist die SKAeroAPI überhaupt dabei? Habe im .pas File eigentlich nur Procedure-Definitionen gesehen, braucht man da noch eine .dcu dazu, die nicht mitgeliefert ist?

venice2 11. Mär 2022 11:48

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Die beiden If/else Zweige führen den gleichen Befehl aus, habe ich da etwas übersehen ?
Nö ;)
Die if Anweisung kannst du eigentlich entfernen ist nicht nötig.

Zitat:

Das Projekt lässt sich nicht compilieren, da er die Unit Graphics nicht findet
Meine Projekte soweit diese nicht 64Bit sind kompiliere ich mit D2010.

Neuere Delphi Versionen benötigen diesen Aufruf.
VCL.Graphics (Ja hier verwende ich noch die VCL aber nicht für einfach Funktionen aus der StrUtils.pas, Forms etc..)

Zitat:

Hast Du irgend eine Art von Dokumentation zu den wichtigsten Befehle der SKAeroAPI.
Nein. Ich habe die Funktionen Prozeduren so Namentlich angepaßt das diese eigentlich selbsterklärend sind.

Zitat:

Ist die SKAeroAPI überhaupt dabei? Habe im .pas File eigentlich nur Procedure-Definitionen gesehen, braucht man da noch eine .dcu dazu, die nicht mitgeliefert ist?
Ja im Ordner _api eine *.dcu wird nicht benötigt diese wird beim kompilieren erstellt.

In uControls kannst du sehen wie bspw. ein Button erstellt wird.
Im Grunde ist das vorgehen immer gleich.

Smiley 11. Mär 2022 12:06

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Wow, superschnelle Antwort und sehr ausführlich mit Frage/Antwort.
Du machst das richtig gut.

VCL.Graphics dachte ich hätte ich als erstes probiert, nun jetzt hat es funktioniert.

Er meldet nur noch, dass ihm die SK_Aero.dll fehlt.
Habe die Bin Dateien mit in das Projektverzeichnis reingenommen, geht trotzdem nicht.
Es wird keine .dll erzeugt.

venice2 11. Mär 2022 12:15

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

SK_Aero.dll
war doch im Archiv vorhanden oder nicht?

Ich schicke dir einen link (PN) zu allen meinen Projekten (samples) such dir aus was du brauchst.
Eigentlich wird in diesen fast alle Funktionen meiner DLL irgendwo behandelt.

Smiley 11. Mär 2022 12:30

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Ups, die .dll war im .rar mit drin, hatte nur das source Verzeichnis kopiert.
Sorry.
Bekomme jetzt eine Exception aus der api.
Auch wenn ich die gesendete Bounce.exe aus dem .rar File ausführe, das ging vorher aber doch schon mal.
Muss gleich mal meinen PC neustarten, ob es dann wieder geht, der macht wieder mal Windows Updates.

venice2 11. Mär 2022 12:37

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Zitat von Smiley (Beitrag 1503173)
Ups, die .dll war im .rar mit drin, hatte nur das source Verzeichnis kopiert.
Sorry.
Bekomme jetzt eine Exception aus der api.
Auch wenn ich die gesendete Bounce.exe aus dem .rar File ausführe, das ging vorher aber doch schon mal.
Muss gleich mal meinen PC neustarten, ob es dann wieder geht, der macht wieder mal Windows Updates.

Du bekommst ein Exception
Delphi-Quellcode:
raise Exception.Create('Skin Config invalid or not available!');

bestimmt deshalb weil du den Ordner für die Ressourcen nicht zu deinem neuen Projekt addiert hast.

Sk_Aero.dll benötigt zum Ausführen die Konfigurationsdatei Bounce.ske (Textdatei) im Skin Ordner.
Dort wird festgelegt welcher Font, Skin, Farben etc.. für das Projekt verwendet werden.
Öffne die einfach mal dann siehst du was ich meine.
Alle Standard Einstellungen für das Fenster werden hier definiert.

Mit Windows Update hat es nichts zu tun.

Smiley 11. Mär 2022 13:01

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Beim compilieren bekomme ich keine Fehler, nur bei der ausführung.
Habe das Skins und SpriteRes Verzeichnis auch noch in das Prjektverz. kopiert und neu kompiliert.
Beim aufrufen der .exe Datei kommt die angehängte Meldung.

venice2 11. Mär 2022 13:04

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Zitat von Smiley (Beitrag 1503175)
Beim compilieren bekomme ich keine Fehler, nur bei der ausführung.
Habe das Skins und SpriteRes Verzeichnis auch noch in das Prjektverz. kopiert und neu kompiliert.
Beim aufrufen der .exe Datei kommt die angehängte Meldung.

Kannst dein Projekt mal anhängen?

Smiley 11. Mär 2022 13:11

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Im Skins Ordner ist ein Ordner Blue mit den Bildern und der Bounce.ske Datei.
Habe versucht die .ske in Skins zu legen, kommt aber der gleiche Fehler.

Smiley 11. Mär 2022 13:14

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mein Project

venice2 11. Mär 2022 13:23

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Zitat von Smiley (Beitrag 1503178)
Hier mein Project

Wenn du den Pfad zur Konfigurationsdatei inklusive der Ressourcen Ordner falsch angibst wird das nix.
Der Pfad in dem die Exe kompiliert wird ist ..\bin dort müssen die Ordner Skin und SpriteRes enthalten sein inklusive der SK_Aero.dll.

Ist das nicht der fall wird ein exception geworfen beim Debuggen und zwar
raise Exception.Create('Skin Config invalid or not available!');


weil die Konfiguration nicht gefunden wird.
Schau doch einfach mal worauf dieser Pfad zeigt.
Delphi-Quellcode:
      DefSkin := BounceIni.ReadString('SkinPath', 'Skin', ExtractFilePath(ParamStr(0))
          + 'Skins\Blue\Bounce.ske');
EDIT:
Machen wir es einfacher.

lösche das in der uIni!
WriteString('SkinPath', 'Skin', WideString(ExtractFileDir(SKAERO_CONFIG_GetSkinFol der)
+ '\Bounce.ske'));

ändere das in uMain
Delphi-Quellcode:
      InitPath;
      DefSkin := BounceIni.ReadString('SkinPath', 'Skin', ExtractFilePath(ParamStr(0))
          + 'Skins\Blue\Bounce.ske');
      BounceIni.Free;
zu
Delphi-Quellcode:
 
DefSkin := ExtractFileDir(ParamStr(0)) + '\Skins\Blue\Bounce.ske';
lösche
Zitat:

'C:\Users\BrewIdeas\AppData\Roaming\BrewIdeas\Boun ce\Bounce.ini'
und gut ist...

Das Problem ist wenn man den Pfad zur Konfigurationsdatei in der INI speichert und du das Projekt nach dem ersten Start
anschließend von einem anderen Pfad ausführst und der alte Pfad zur Ini (siehe erster Start) nicht mehr existiert wirft die Anwendung ein Exception.
Deshalb habe ich die Speicherung des Pfad jetzt mit diesen Änderungen aus der INI herausgenommen.

Smiley 11. Mär 2022 14:18

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Habe den Fehler jetzt gefunden.
Der DefSkin Path war schon richtig, denn der Skins Ordner liegt im gleichen Ordner wie die .exe Datei.
Das Problem ist der Eintrag in der .ini Datei für den SkinPath.
Dieser wird nur beim ersten Aufruf des Programmes einmal gesetzt und liest ihn dann immer wieder, auch wenn die .exe jetz an einem anderen Ort liegt.
Dort war noch der Pfad aus der entpackten .rar Datei im Temp Verzeichnis drin, da ich beim ersten Versuch direkt aus der .rar Datei die .exe aufgerufen haben.
Nachdem ich die .rar datei geschlossen hatte, wurden dann auch die Dateien dort gelöscht und er konnte nichts mehr finden.

Man könnte das vermeiden, indem man, falls die Datei nicht gefunden wird, nochmal unter dem Pfad der .exe sucht.

Mich stört es, wenn mein Programm noch ein Verzeichnis davor braucht um die .exe zu speichern, daher lege ich die .exe entweder in das Projektverzeichnis oder wenn zur Exe noch andere Dateien gehören, dann lege ich die unter Projekt\_bin damit alles in einem Verzeichnis bleibt.
Das kann aber jeder für sich anders machen.

Das Problem hier war eigentlich nur, dass man die .exe Datei mit ihren Ordnern nicht verschieben darf, wenn es einmal gestartet wurde, da es den Pfad immer aus der .ini Datei liest und nicht mehr neu prüft. Dann brauche ich immer eine Setup Routine zum installieren des Programmes, die die .ini Datei dann neu anlegt.

Vielen Dank Venice2 dass Du Dir so viel Mühe mit mir gibst und mir weiterhilfst wenns mal nicht klappt.
Danke Danke Danke!!!

venice2 11. Mär 2022 14:53

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Zitat:

Das Problem ist der Eintrag in der .ini Datei für den SkinPath.
Jo schrieb ich ja und wie man es ändern kann auch :)
Zitat:

Das Problem ist wenn man den Pfad zur Konfigurationsdatei in der INI speichert und du das Projekt nach dem ersten Start
anschließend von einem anderen Pfad ausführst und der alte Pfad zur Ini (siehe erster Start) nicht mehr existiert wirft die Anwendung ein Exception.
Deshalb habe ich die Speicherung des Pfad jetzt mit diesen Änderungen aus der INI herausgenommen.
Zitat:

Mich stört es, wenn mein Programm noch ein Verzeichnis davor braucht um die .exe zu speichern, daher lege ich die .exe entweder in das Projektverzeichnis oder wenn zur Exe noch andere Dateien gehören, dann lege ich die unter Projekt\_bin damit alles in einem Verzeichnis bleibt.
Das kann aber jeder für sich anders machen.
Richtig!
Zitat:

Vielen Dank Venice2 dass Du Dir so viel Mühe mit mir gibst und mir weiterhilfst wenns mal nicht klappt.
Danke Danke Danke!!!
Kein Problem. ;)
Wenn was ist melde dich einfach.

Smiley 11. Mär 2022 15:44

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Ja mach ich.
Unsere Meldungen haben sich überschnitten, war noch am suchen und schreiben, da hast Du schon geantwortet, das habe ich erst gesehen, nachdem ich es abgeschickt habe.
Änderung ist schon eingebaut.

Jetzt muss ich mich aber wieder mal meinem eigentlichen, kleinerem Problem zuwenden, wie ich mein einfaches Lernprojekt fortsetze.
Zu Anfang dachte ich es sei leichter mit einem TPanel und einem TShape darauf zu arbeiten, da man dafür die x und y Koordinaten für den linken oberen Punkt übergeben muss und sich nicht wie bei einem gezeichneten Kreis noch mit Mittelpunkt vom Kreis und linkem Rand vom Kreis beschäftigen muss.
Das geht aber auch wenn ich ein Rechteck zeichne und später den Kreis.
Außerdem kann man auch mit einem Image arbeiten und das bewegen.

Jetzt habe ich mich erst mal für eine Painbox entschieden auf die ich dann ein Rechteck zeichne.
Die Randprüfung überfordert die meisten Anfänger schon.

Ich nehme also eine Form und setze eine Paintbox darauf.
Mit Ball := TBall.Create(Paintboxname); erstelle ich dann einen Ball in der MainForm.
im TBall Objekt übernehme ich diese PB dann mit
in der Typ Deklaration und rufe es auf mit
Code:
constructor Create (AOwner: TPaintbox);
und in der Implementierung mit
Code:
constructor Tball.Create (AOwner: TPaintbox);
Hier initialisere ich meine Variable und erstelle meinen Timer für den Ball.
Code:
Inherited;
BallTimer := TTimer.Create(nil);
BallTimer.OnTimer := OnBallTimer;
Im OnBallTimer Ereignis kann ich dann den Ball, mit berechneten Koordinaten, auf dem canvas der übergebenen Paintbox, zeichnen.

Das funktioniert schon mal.

Was ist mit dem override beim Constuctor ? Brauche ich das ?

Kann ich in der MainForm auch ein Image verwenden und TBall erkennt das anhand der übergebenen Componente ?

venice2 11. Mär 2022 16:00

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Wenn BallTimer innerhalb der class TForm definiert ist dann kannst du meines Erachtens es auch so erstellen.
Delphi-Quellcode:
BallTimer := TTimer.Create(self);
Zitat:

Kann ich in der MainForm auch ein Image verwenden und TBall erkennt das anhand der übergebenen Componente ?
Gehe ich mal von aus. Obwohl ich nicht so viel mit VCL.Forms zu tun habe.
Einfach mal versuchen. ;)

Smiley 11. Mär 2022 16:13

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben
 
Nein der Timer liegt nicht im MainForm, das den Ball aufruft.
MainForm legt eine Instanz von BallA an und der Ball soll auf der Paintbox oder dem Image von MainForm laufen.
Der Timer wird in TBall erstellt.
MainForm kann eine weitere Ball-Instanz erstellen und zusätzlich auf der Paintbox oder auch einem anden Control laufen lassen.
Der zweite Ball kann mit BallB.Speed z.B. auch eine andere Geschwindigkeit haben und eine andere Größe (BallB.Size).


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz