Canvas->Draw() erzeugt Exception?
-
hab ich schon ich habe 2 bitmaps mit new erzeugt und ein paar TRect
und habe alles mit delete wieder gelöschtXBert
-
Hallo
Der Speicherverbrauch und die Exception kommen aber nicht von ListView selber, sondern von deinem Code. Vielleicht solltest du mal einzelne Teile des fraglichen Quellcodes ausklammern um zu sehen wann das fehlerhafte Verhalten verschwindet.
So oder so können wir hier ohne Einsicht in deinen Quellcode nur raten.bis bald
akari
-
Ok dann Poste ich hier den Code:
void __fastcall TForm1::ListView1DrawItem(TCustomListView *Sender, TListItem *Item, TRect &Rect, TOwnerDrawState State) { Graphics::TBitmap *prog= new Graphics::TBitmap(); Graphics::TBitmap *prog1= new Graphics::TBitmap(); TRect mainRect,Progress,addInf,temp,Abort,showDialog; mainRect.Left=Rect.Left; mainRect.Top=Rect.Top+1; mainRect.Right=Rect.Left+ListView1->Columns->operator [](0)->Width-2; mainRect.Bottom=Rect.Bottom; Progress.Left=Rect.Left+ListView1->Columns->operator [](0)->Width; Progress.Top=Rect.Top; Progress.Right=Progress.Left+ListView1->Columns->operator [](1)->Width-2; Progress.Bottom=Rect.Bottom; addInf.Left=Progress.Right+2; addInf.Top=Rect.Top+1; addInf.Right=addInf.Left+ListView1->Columns->operator [](2)->Width-1; addInf.Bottom=Rect.Bottom; showDialog.Left=addInf.Right+2; showDialog.Top=Rect.Top; showDialog.Right=showDialog.Left+ListView1->Columns->operator [](3)->Width-1; showDialog.Bottom=Rect.Bottom; Abort.Left=showDialog.Right+2; Abort.Top=Rect.Top; Abort.Right=Abort.Left+ListView1->Columns->operator [](4)->Width-1; Abort.Bottom=Rect.Bottom; // Aktions-Namen-Balken ListView1->Canvas->TextRect(mainRect,mainRect.Left+20,mainRect.Top+2,Item->Caption ); //Icons int k = 16; TIcon *myIcon=new TIcon(); if(Item->Caption=="Kopieren")k=0; else if(Item->Caption=="Ausschneiden")k=1; else if(Item->Caption=="Löschen")k=2; else if(Item->Caption=="Freigabe(n) aufheben")k=3; else if(Item->Caption=="Vergleichen")k=4; else if(Item->Caption=="Verschlüsseln")k=5; else if(Item->Caption=="Neue(n) Ordner erstellen")k=6; else if(Item->Caption=="Neue(n) Registry-Schlüssel erstellen")k=7; else if(Item->Caption=="Verpacken")k=8; else if(Item->Caption=="Umbenennen")k=9; else if(Item->Caption=="Freigeben")k=10; else if(Item->Caption=="Shreddern")k=11; else if(Item->Caption=="Teilen")k=12; else if(Item->Caption=="Synchronisieren")k=13; else if(Item->Caption=="Entschlüsseln")k=14; else if(Item->Caption=="Entpacken")k=15; icons->GetIcon(k,myIcon); ListView1->Canvas->Draw(mainRect.Left+2, mainRect.Top+2,myIcon); DestroyIcon(myIcon); // Fortschritts-Balken ImageList1->GetBitmap(0,prog); ImageList1->GetBitmap(1,prog1); double proz=StrToFloat(Item->SubItems->operator [](0)); int pixel; pixel=(proz/100)*(Progress.Right-Progress.Left); for(int i=0;i< pixel;i++){ ListView1->Canvas->Draw(Progress.Left+i,Progress.Top,prog ); } for(int i=pixel;i<(Progress.Right-Progress.Left);i++){ ListView1->Canvas->Draw(i+Progress.Left,Progress.Top,prog1 ); } /* //Prozentanzeige --vv-- (funktioniert nicht) int textLeft=(ListView1->Columns->operator [](1)->Width - ListView1->Canvas->TextWidth(Item->SubItems->operator [](0)))/2 + mainRect.Width() ; int textTop= (mainRect.Height() - ListView1->Canvas->TextHeight(Item->SubItems->operator [](0)))/2 ; temp.Left=textLeft; temp.Top=textTop; temp.Right=textLeft+ListView1->Canvas->TextWidth(Item->SubItems->operator [](0)); temp.Bottom=textTop+ListView1->Canvas->TextHeight(Item->SubItems->operator [](0)); ListView1->Canvas->Font->Color=clBlack; ListView1->Canvas->TextRect(temp,temp.Left,temp.Top,(Item->SubItems->operator [](0)) ); */ //Zusätzliche Informationen ListView1->Canvas->TextRect(addInf,addInf.Left,addInf.Top,Item->SubItems->operator [](1) ); //Dialog/Abbrechen - Buttons ListView1->Canvas->Draw(showDialog.Left,showDialog.Top,Image1->Picture->Graphic); ListView1->Canvas->Draw(Abort.Left,Abort.Top,Image2->Picture->Graphic); //Speicher freigeben delete prog1,mainRect,addInf,prog,temp,Abort,showDialog; }Ich hoffe,dass das weiterhilft.
LG XBert
-
Hallo
Ohne jetzt alles genau überprüft zu haben kann ich schon,al sagen das diese Zeile hier nicht das macht was du erwartest :
delete prog1,mainRect,addInf,prog,temp,Abort,showDialog;Der Kommaoperator ist nämlich hier falsch, es wird nur das letzte Argument verwendet. Alle anderen werden nur "angefasst" aber nicht verarbeitet.
Du must schon jedes Objekt einzeln löschen
delete prog1; delete mainRect; ... delete showDialog;bis bald
akari
-
Danke das wusste ich nicht.
Aber ich nehme an, dass ich die ganzen TRect als pointer definieren muss
um sie Löschen zu können oder sollte das auch so funktionieren (ohne Löschen der TRect)?LG XBert
-
Hallo
Nein Löschen must du nur, was du mit new auch anlegst. Wenn du etwas ohne new auf dem Stack anlegst wird die Instanz automatisch gelöscht. Und wenn du etwas auf dem Stack anlegen kannst wie die TRects dann solltest du das auch machen. Bei TBitmap geht das leider nicht also must du dort mit new und delete arbeiten.
In diesem speziellen Fall beschränkt sich das Löschen auf die TBitmaps.
bis bald
akari
-
Ok danke das hab ich nie gelernt.
Aber ich hab noch ein memoryleak gefunden weil ich dachte das TIcon mit DestroyIcon()
gelöscht wird. Aber man muss es danach auch noch mit delete "zerstören".Aber eine Frage hab ich noch:
Was machtint j=17; delete &j;LG XBert
-
Hallo
XBert schrieb:
Ok danke das hab ich nie gelernt.
Aber ich hab noch ein memoryleak gefunden weil ich dachte das TIcon mit DestroyIcon()
gelöscht wird. Aber man muss es danach auch noch mit delete "zerstören".Das delete dürfte ausreichen, das DeleteIcon brauchst du nicht.
Aber eine Frage hab ich noch:
Was machtint j=17; delete &j;Ärger. Denn das ist nicht erlaubt. Da j eine Stack-Variable ist und nicht auf dem Heap angelegt wurde, wird es auch automatisch beim Verlassen des Gültigkeitsbereiches gelöscht. Wenn du nun trotzdem delete auf die Instanz anwendest wird das Löschen zweimal ausgeführt, was in der Regel zu einem Speicherzugriffsfehler führt.
bis bald
akari
-
der Compiler nimmt es aber an und es wird keine Exception ausgelöst
LG XBert
-
Hallo
Dann hast du Glück (oder Pech?). Denn es ist ungültig. Und da kann alles mögliche passieren.
bis bald
akari