Warum funktioniert Drucken nur ein mal?
-
Habe da einen Fehler den ich nicht finde. Wenn ich meinen Drucken Button betätige, Wird mein Frame ausgedruckt. Wenn ich den Button nochmals betätige, hängt er sich in der if Anweisung auf und bringt eine Speicherverletztung. Aber warum?
if(pPrintDialog->Execute())void __fastcall TFormGrundbild::SBDruckenClick(TObject *Sender) { // Druckdialog dynamisch erzeugen TPrintDialog *pPrintDialog1 = new TPrintDialog(this); // Druckdialog Optionen löschen pPrintDialog1->Options.Clear(); // Auf Seite 1 stellen pPrintDialog1->FromPage = 1; // Mindestseiten auf eine stellen pPrintDialog1->MinPage = 1; // Angabe der Bis Seitenzahl aktivieren pPrintDialog1->ToPage = 1; // Drucken bis Maximal Ende Seiten pPrintDialog1->MaxPage = 1; // Printdialog ausgeführt if(pPrintDialog1->Execute()) //<<------------------hier hängt er sich beim zweiten mal Drucken auf { // Drucker dynamisch erzeugen TPrinter *pPrinter = Printer(); // Seite festlegen TRect r = Rect(0, 0, pPrinter->PageWidth, pPrinter->PageHeight); // Druckbereich festlegen TRect rSeite = Rect(200, 200, pPrinter->PageWidth - 200, pPrinter->PageHeight- 200); // Bitmap erzeugen Graphics::TBitmap *Printbmp=new Graphics::TBitmap; // Breite Frame an Bitmap übergeben Printbmp->Width = FormGrundbild->AktuellFrame->Width; // Höhe Frame an Bitmap übergeben Printbmp->Height = FormGrundbild->AktuellFrame->Height; // Drucktitel pPrinter->Title = "Frame"; // Drucker auf Querformat einstellen pPrinter->Orientation = poLandscape; // Druckauftrag beginnen pPrinter->BeginDoc(); // Frame in Bitmap zeichnen FormGrundbild->AktuellFrame->PaintTo(Printbmp->Canvas,10,10); // Drucker Rechteck vorgeben pPrinter->Canvas->Rectangle(r); // gestrecktes Bild in Printer übergeben pPrinter->Canvas->StretchDraw(rSeite,Printbmp); // Handle setzen pPrinter->Canvas->Handle; // Dokument beenden pPrinter->EndDoc(); // Bitmap löschen delete Printbmp; // Drucker löschen delete pPrinter; } // Wenn PrintDialog besteht if(pPrintDialog1) { // Printdialog löschen delete pPrintDialog1; // PrintDialog auf Null setzen pPrintDialog1 = NULL; } }
-
Du solltest auch nur das löschen, was dir gehört.
Und den Drucker zu löschen, ist ganz böse...
P.S. die letzten Zeilen sind überflüssig, es reicht ein einfaches
delete pPrintDialog1;Ich nehme mal an, du fragst demnächst auch mal die Werte aus dem Dialog ab, denn so wäre er ja überflüssig...
-
Jetzt wo du mir das sagst ist das auch einleuchtend, erzeuge ja keinen neuen Drucker, sondern benutze die im System vorhandenen.
Zur Abfrage des PrintDialogs.
Ich stelle den PrintDialog auf eine Seite ein. Der Benutzer soll da keine weitere Auswahl haben, außer vielleicht einen anderen Drucker und das Papierfach zu wählen. Alles andere sperre ich.Das passt dann schon.
Danke
egcactus
-
Wobei du das hier
// Wenn PrintDialog besteht if(pPrintDialog1) { // Printdialog löschen delete pPrintDialog1; // PrintDialog auf Null setzen pPrintDialog1 = NULL; }auch ohne einen Fehler zu machen durch das hier ersetzen kannst
delete pPrintDialog1;
Noch besser wäre es, wenn du dafür einen Smartpointer (hier geht auto_ptr) nimmst. Dann brauchst du gr kein delete.
Also das hierTPrintDialog *pPrintDialog1 = new TPrintDialog(this);durch das hier ersetzen
std::auto_ptr<TPrintDialog> pPrintDialog1(new TPrintDialog(0));und schon ist kein delete mehr nötig.
-
Ok, das funktioniert und nun habe ich eine neue Aufgabe. Erst mal nachlesen, was Autopointer sind und wie und für was man die benutzen kann.
Danke für die Hilfe.
Grüße
egcactus
-
Dann mal was zum Lesen.
Hier ein Artikel aus dem Magazin über die boost-Smartpointer. auto_ptr wird da kurz erwähnt.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-134971.html
über auto_ptr
http://www.hlrs.de/people/mueller/tutorials/script/scriptse36.html