Zugriffsverletzung bei der Programmausführung



  • Vielleicht kann mal jemand einen Tipp geben, warum bei einem Zugriff auf das Graphics-Objekt "zeichenflaeche" in einem Eventhandler eine Zugriffsverletzung bei der Programmausführung kommt. Außerhalb eines Eventhandlers funktioniert es.

    Unit1.h: auszugsweise Deklaration:

    private: // Benutzer-Deklarationen
        std::unique_ptr<Graphics::TBitmap> DrawingBoard;
        Gdiplus::Graphics* zeichenflaeche;
        DWORD pdwGdiStartup;
        Gdiplus::GdiplusStartupInput GdiStartupInp;
    

    Unit1.cpp: auszugsweise

    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
        ...
        Gdiplus::Graphics* zeichenflaeche = new Gdiplus::Graphics(DrawingBoard->Canvas->Handle);
    

    ... und im Eventhandler:

    void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button,
        TShiftState Shift, int X, int Y) {
    
      zeichenflaeche->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
      ...
    

    Hat jemand eine Idee?
    Danke!



  • Du solltest NICHT im Constructor der Form eine lokale Variable "Zeichenfläche" mit ...new... belegen.

    1. Der Handler sieht diese NICHT, der sieht die in der Headerdatei deklarierte Variable!

    2. Am Ende des Constructors wird der Speicher NICHT freigegeben => Speicherloch!

    3. Nutze IMMER nur die in der Headerdatei deklarierte Variable!
    Die ist auch im Handler sichtbar.
    Die MUSS im Destrultor auch freigegeben werden!

    Gruss
    Frank



  • Am besten benutzt du auch hier einen smarten pointer.



  • Habe jetzt überall Smartpointer benutzt:
    In Unit1.h.:

    std::unique_ptr<Gdiplus::Graphics> zeichenflaeche;
    	std::unique_ptr<Gdiplus::Pen> Stift;
    

    In Unit1.cpp eigene Methode:

    void TForm1::Initialisierung()
    {
    ...
    	zeichenflaeche.reset(new Gdiplus::Graphics(DrawingBoard->Canvas->Handle));
    	Stift.reset(new Pen(Gdiplus::Color(255, 0, 0, 255), StrichMiddle));
    ...
    

    erhalte jetzt aber den Fehler

    E2285 Keine Übereinstimmung für 'Graphics::DrawLine(std::unique_ptr<Pen,std::default_delete<Pen> > *,int,int,int,int)' gefunden
    

    in Zeile

    zeichenflaeche->DrawLine(Stift, X, Y, X+1, Y);
    


  • Ist das wirklich die zeile aus dem quelltext. Laut Fehlermeldung versuchst du, einen zeiger auf einen unique_ptr<Pen> zu übergeben.



  • DrawLine benötigt doch als ersten Parameter einen Pointer. Oder muss man einen unique_ptr erst noch umwandeln?



  • ja klar:
    Stift.get() !!!



  • Aber:
    warum kann ich per

    zeichenflaeche.reset(new Gdiplus::Graphics(GetWindowDC(GetDesktopWindow())));
    

    auf das Fenster eine Linie zeichnen, aber nicht per

    zeichenflaeche.reset(new Gdiplus::Graphics(DrawingBoard->Canvas->Handle));
    

    auf das Bitmap DrawingBoard?
    Für beides habe ich in der MouseMove-Event einer Paintbox folgendes:

    ...		zeichenflaeche->DrawLine(Stift.get(), LinienstartX, LinienstartY, X, Y);
    ...
    

Log in to reply