Komponente darstellen



  • Ich habe eine Delphi Komponente in meinem CBuilder5 und komme gerade damit leider nicht ganz klar.

    Die Komponente bringt mehrere Klassen mit.
    Eine große Klasse namens "Block" und Subclasses die das Aussehen bestimmen.

    Zum Beispiel

    Rect = class(Block)
      private
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure DrawBlock(G: TGPGraphics); override;
      published
      end;
    
      Ellipse = class(Block)
      public
        procedure DrawBlock(G: TGPGraphics); override;
        function PtOnBlock(X, Y: Float): boolean; override;
      published
        constructor Create(AOwner: TComponent); override;
      end;
    
      Line = class(Block)
      private
      public
        procedure DrawBlock(G: TGPGraphics); override;
        function PtOnBlock(X, Y: Float): boolean; override;
      published
        constructor Create(AOwner: TComponent); override;
      end;
    

    Das mache ich dann für das Rechteck in CBuilder so

    Block *block = new Ddoc::Rect(BlockEditor->Document);
    

    Mein Problem ist jetzt, dass ich dies auch gern für diese Image Subclass machen möchte

    Image = class(Block)
      private
        FBitmap: TGraphic;
        FB: array of TGPImage;
        FUndoLinkIndex: integer;
        procedure SetImage(const Value: TGraphic);
        function GetImage: TGraphic;
        function IsRealStream: Boolean;
        function IsUndoStream: Boolean;
        function GetUndoLink: string;
        procedure SetUndoLink(const Value: string);
        procedure Loaded; override;
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure DrawBlock(G: TGPGraphics); override;
      published
        property Image: TGraphic read GetImage write SetImage stored IsRealStream;
        property UndoLink: string read GetUndoLink write SetUndoLink stored IsUndoStream;
      end;
    

    Und das hier ist mein C++ Code dazu der fehlerfrei compiliert wird, ein Block auch eingefügt, aber man sieht diesen nicht.

    Block *block = new Ddoc::Image(BlockEditor->Document);
    
        TJPEGImage *jpg = new TJPEGImage();
        jpg->LoadFromFile("bild.jpg");
        Ddoc::Image(block).Image = jpg;
    
        BlockEditor->Document->AddBlock(block);
    
        block->Left = 5;
        block->Width = 100;
        block->Top = 5;
        block->Height = 100;
    

    Auch als Bitmap bewirkt es nichts

    Graphics::TBitmap *bitmap = new Graphics::TBitmap();
        bitmap->LoadFromFile("bild.bmp");
        Ddoc::Image(block).Image = bitmap;
    

    Sieht eventuell jemand meinen Fehler? Wäre echt super wenn mich jemand dahingehend aufklären könnte. Bin schon am verzweifeln ^^°



  • Wieso kann eigentlich Delphi mit TGraphic so einfach arbeiten und wir müssen das mit Bitmap machen?

    Btw in Delphi wird das Image so hinzugefügt. Man zieht einen Rahmen auf einer Zeichenfläche namens BlockEditor, dadurch wird ein Event losgeschickt das diese Funktion aufruft:

    procedure TForm1.BlockEditor1BlockEditImage(Sender: TObject;
      var Bitmap: TGraphic);
    begin
      if OpenPictureDialog1.Execute then
      begin
        Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
    
        Bitmap := TGraphic(Image1.Picture.Graphic.ClassType.Create);
        Bitmap.Assign(Image1.Picture.Graphic);
      end;
    end;
    

    Anschließend hat man einen Block mit einer Grafik.

    Sowas cooles kann Cbuilder leider nicht. Wie würde denn das in CBuiler ausschauen? Mein Code oben bewirkt ja leider nichts. 😞

    Bitmap := TGraphic(Image1.Picture.Graphic.ClassType.Create);
    

    Ich muss passen, ich weiss nicht mehr weiter. Ich hoffe hier hat jemand von TGraphic etwas mehr Ahnung als meiner einer und die Lust mich zu unterstützen. 🙂



  • Der Delphi-Code ist auch nicht ganz korrekt; richtig wäre das vermutlich so:

    Bitmap := TGraphicClass (Image1.Picture.Graphic.ClassType).Create;
    

    ~Felix schrieb:

    Sowas cooles kann Cbuilder leider nicht. Wie würde denn das in CBuiler ausschauen? Mein Code oben bewirkt ja leider nichts. 😞

    Virtuelle Konstruktoren können, anders als in Delphi, in C++-Code nicht über Klassenreferenzen aufgerufen werden. Du müßtest dir eine Wrapperfunktion schreiben:

    function CreateGraphic (GraphicClass: TGraphicClass): TGraphic;
    begin
      Result := GraphicClass.Create;
    end;
    
    void __fastcall TForm1::BlockEditor1BlockEditImage (TObject* Sender, TGraphic*& Bitmap)
    {
        if (OpenPictureDialog1->Execute ())
        {
            Image1->Picture->LoadFromFile (OpenPictureDialog1->FileName);
            Bitmap = CreateGraphic (static_cast <TGraphicClass> (Image1->Picture->Graphic->ClassType ());
            Bitmap->Assign (Image1->Picture->Graphic);
        }
    }
    


  • Wau! hatte schon die Befürchtung keiner kann mir helfen. Vielen lieben Dank für die Erklärung und den helfenden Code!

    Allerdings habe ich leider immer noch mein Problem mit diesem Code. Er compiliert, aber zu Laufzeit verursacht er eine böse Zugriffsverletzung.

    TJPEGImage *image = new TJPEGImage();
        image->LoadFromFile("image.jpg");
    
        Ddoc::Image(block).Image = CreateGraphic(static_cast<TGraphicClass>(image->ClassType()));
    

    😞



  • Ich habe auch mal den Umweg über ein Image gemacht. Das Ergibt nun keine Fehlermeldung mehr, aber die Grafik wird mir damit leider immer noch nicht angezeigt. Was ein Fluch. 🙄

    Block *block = new Ddoc::Image(BlockEditor1->Document);
        BlockEditor1->Document->AddBlock(block);
    
        TJPEGImage *image = new TJPEGImage();
        image->LoadFromFile("image.jpg");
        Image1->Picture->Assign(image);
    
        TGraphic *Bitmap = Ddoc::Image(block).Image;
        Bitmap = CreateGraphic(static_cast<TGraphicClass>(Image1->Picture->Graphic->ClassType()));
        Bitmap->Assign(Image1->Picture->Graphic);
    


  • Hi,

    sollte man dem Bitmap nicht sagen, wie sein Width und sein Height sein sollte?

    mfg
    kpeter



  • Nicht im diesem Falle. Es ist ein Jpeg das in ein TImage geladen wird. Das hat eine Größe, sogar mit Autosize die korrekte Größe.



  • ~Felix schrieb:

    Allerdings habe ich leider immer noch mein Problem mit diesem Code. Er compiliert, aber zu Laufzeit verursacht er eine böse Zugriffsverletzung.

    TJPEGImage *image = new TJPEGImage();
        image->LoadFromFile("image.jpg");
    
        Ddoc::Image(block).Image = CreateGraphic(static_cast<TGraphicClass>(image->ClassType()));
    

    Vermutlich hast du Ddoc::Image (block).Image->Assign (image); vergessen.

    Folgendes funktioniert bei mir ganz hervorragend (Speicherlecks ausgenommen):

    TJPEGImage *jpgImage = new TJPEGImage;
        jpgImage->LoadFromFile ("image.jpg");
        TGraphic* graphic;
        graphic = CreateGraphic (static_cast <TGraphicClass> (jpgImage->ClassType()));
        graphic->Assign (jpgImage);
        Image1->Picture->Graphic = graphic;
    


  • Danke für die Hilfe. Total verpennt das noch was kam 🙂
    Inwiefern gibt es da eigentlich Speicherlecks?
    Die Komponente bekomme ich leider aber immer noch nicht hin. Da scheint andersweitig noch etwas zu fehlen.


Anmelden zum Antworten