tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
6
ZUGRIFFE
2598
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Chronix Chronix ist offline Mitglied Gold
    Registriert seit
    May 2004
    Ort
    Duisburg
    Beiträge
    143
    Irgendwie scheine ich gerade (5 Uhr nachts) ein Brett vor dem Kopf haben.. finde hier den Fehler nicht.... kann irgendwer mal nen Anstoß geben?

    Gedacht ist das ganze bloß so, dass ich eine von TCanvas abgeleitete Klasse erstelle, der Ecke links oben den Mittelpunkt der Zeichenfläche als Ausgangspunkt nutzt.
    Habe um ein entsprechendes Image zu haben auch gleich eine von TImage abgeleitete Klasse erstellt, die dann meine Canvas enthält.

    Klassendefinitionen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    type
        TMidCanvas = class(TCanvas)
        private
            MidX, MidY : Integer;
        public
            Constructor Create( X, Y : Integer);
            procedure MoveTo( x, y : Integer);
            procedure LineTo( x, y : Integer);
    end;
     
    type TMidImage = class(TImage)
        public
            Canvas : TMidCanvas;
            constructor Create( owner: TComponent);
    end;


    Implementation:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    Constructor TMidCanvas.Create( X, Y : Integer);
    begin
    inherited Create;
    MidX:= x;
    MidY:= y;
    end;
     
    procedure TMidCanvas.MoveTo( x, y : Integer);
    begin
    inherited MoveTo( MidX + x, MidY - y);
    end;
     
    procedure TMidCanvas.LineTo( x, y : Integer);
    begin
    inherited LineTo( MidX + x, MidY - y);
    end;
     
    constructor TMidImage.Create( owner: TComponent);
    begin
    inherited Create(owner);
    self.Canvas:= TMidCanvas.Create( Width div 2, Height div 2);
    end;



    Wenn ich nun zur Laufzeit ein Image erzeuge und die Bounds gesetzt habe, kommt sobald ich darauf zeichnen möchte die Fehlermeldung ich könnte auf die Zeichenfläche nicht zeichnen.
    Geändert von Chronix (14.01.08 um 13:31 Uhr)
     

  2. #2
    Registriert seit
    Mar 2004
    Beiträge
    441
    Also spontan sehe ich erstmal nur, dass du in deiner TMidImage-Klasse als Canvas dennoch nur den normalen TCanvas und nicht deinen TMidCanvas verwendest.

    Ansonsten wäre eine detaillierte Fehlermeldung und der Fehlerort (Debugger) hilfreich.
     

  3. #3
    Chronix Chronix ist offline Mitglied Gold
    Registriert seit
    May 2004
    Ort
    Duisburg
    Beiträge
    143
    Hast Recht, hatte da die falsche Klasse angegeben.
    Ändert trotzdem nichts am Fehler!

    Beim Aufruf von TMidImage.MoveTo wird ein EInvalidOperation Fehler erzeugt.
    Fehlermeldung: Leinwand/Bild erlaubt kein Zeichnen.
     

  4. #4
    Registriert seit
    Mar 2004
    Beiträge
    441
    Die kurze Antwort: Deinem Canvas fehlt der Handle für den DeviceContext (HDC).
    Nähere Informationen zum Device Context kannst du hier finden.
    Das Standard-TImage verwendet u.a. eine TBitmap und genau diese wiederum liefert auch den HDC für ihre TCanvas-Komponente.

    Dein TMidImage legt also eine Möglichkeit an, um verschiedenartig zu zeichnen (TMidCanvas:TCanvas), versäumt es dann aber, dem TMidCanvas mitzuteilen, wo seine Leinwand (also er selbst) überhaupt dargestellt werden soll.

    So habe ich das zumindest nach Durchsicht diverse VCL-Sources verstanden.
     

  5. #5
    Chronix Chronix ist offline Mitglied Gold
    Registriert seit
    May 2004
    Ort
    Duisburg
    Beiträge
    143
    Ahaaa, das hört sich doch sehr interessant an.
    Ich dachte die Information wo das zeichnen genau zu erfolgen hat hätte TCanvas bereits durch die Übergabe von parent im Konstruktor.

    Werde mich mal einlesen!
     

  6. #6
    Registriert seit
    Mar 2004
    Beiträge
    441
    Zitat Zitat von Chronix Beitrag anzeigen
    Ich dachte die Information wo das zeichnen genau zu erfolgen hat hätte TCanvas bereits durch die Übergabe von parent im Konstruktor.
    Dachte ich auch. Deswegen habe ich mir mal den Spaß gegönnt und ein bißchen in den VCL-Sourcen gestöbert (Volltextsuche in Dateien sei Dank). Dabei bin ich darüber gestolpert, dass die TCanvas-Klasse u.a. ein State-Flag hat (private). Dieses gibt an, ob dem Canvas ein gültiger HDC zugeordnet wurde oder nicht. Bei allen Canvas-Operationen (wie z.B. dem MoveTo) wird vorher immer überprüft, ob dieses State-Flag durch Setzen eines HDC initialisiert wurde. Und genau das habe ich im Konstruktor vom TCanvas gefunden:
    Code delphi:
    1
    2
    
    ...
    State := [];
    Sprich: Es ist völlig egal, was du dem TCanvas bei der Initialisierung mitgibst, der State bleibt erstmal auf "ich habe keinen HDC". Der muss dann nach der Initialisierung von der entsprechenden Containerklasser (TImage, TBitmap, TSchiessmichtot) gesetzt werden.

    In meinem eigenen Projekt hier verwende ich ein einziges TImage und zahlreiche TBitmaps. Das TImage dient nur als Viewport zur skalierbaren Anzeige von Bildern, sämtliche Bildmanipulationen á la TCanvas.MoveTo() laufen über TBitmaps ab, die ich dann auf die Bitmap des TImage blitte. Funktioniert bis dato ziemlich gut.
     

  7. #7
    Chronix Chronix ist offline Mitglied Gold
    Registriert seit
    May 2004
    Ort
    Duisburg
    Beiträge
    143
    Sehr interessant
    Hat was gedauert, bis ichs wieder hier gelesen habe... hatte nicht viel zeit!

    Werde das mal versuchen einzubinden.

    Deine Variante mit den Bitmaps halte ich bei mir nicht so für gelungen, da ich ja ansich nur alle TCanvas Zeichenfunktionen auf den Mittelpunkt eines Bildes, statt auf den linken oberen Punnkt beziehen möchte.

    Das ganze soll später nen karthesisches Koordinatensystem zu realisieren, in dem mitunter auch Leute aus einem Schul-Info-Kurs halbwegs gewohnt zeichen können.
    Von daher würde ich da gerne den direkten Weg gehen einfach durch ne zwischengeschaltete Klasse den Zeichenpunkt zu verschieben.

    Werde mal sehen ob ich das State Flag hinbekomme
     

Ähnliche Themen

  1. Ableitung von Vector<E>
    Von theLMF im Forum Java
    Antworten: 3
    Letzter Beitrag: 18.10.07, 08:42
  2. TImage
    Von ZeroGirl im Forum Delphi, Kylix, Pascal
    Antworten: 1
    Letzter Beitrag: 19.01.06, 17:44
  3. TreeView ableitung, DragDrop?
    Von Trivalik im Forum .NET Web und Kommunikation
    Antworten: 1
    Letzter Beitrag: 20.09.05, 09:42
  4. TButton und Ihre Wiederspenstige Ableitung
    Von xyzPainter im Forum Borland CBuilder und VCL
    Antworten: 0
    Letzter Beitrag: 16.08.04, 19:22
  5. Mathe :) dif VS Ableitung
    Von vinc5nt im Forum Smalltalk
    Antworten: 0
    Letzter Beitrag: 04.12.01, 16:15