Laden...

Drucken eines Controls?

Erstellt von dschmoegner vor 18 Jahren Letzter Beitrag vor 13 Jahren 83.632 Views
D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren
Drucken eines Controls?

Hallo,

besteht die Möglichkeit ein Windows Control zu drucken? Ich arbeite mit ZedGraph von Sourcefourge.net und erzeuge mir damit ein Diagramm. Nun möchte ich gerne dieses Diagramm drucken. Allerdings möchte ich nicht im Quellcode von ZedGraph herumpfuschen. Den Graph selber kann man als Image speichern, was aber nur über Rechte Maustaste->Kontextmenue geht. Kann ich ein Control an den Drucker übergeben?

Schon mal danke.

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Die Idee, das Control an den Drucker zu übergeben war wohl ne Schnapsidee. 🙁

Jetzt hatte ich mir überlegt, das Diagramm Control an eine neue Form zu übergeben und diese neue Form zu drucken ohne sie dabei anzuzeigen. Allerdings finde ich da keinen Zugang. In der MSDN wird auch nix über Screenshot oder ählichem geschrieben.

Heisst das der Drucker kann nur Graphics Elemente verarbeiten und es ist absolut unmöglich das Control irgendwie zu drucken? X(

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

Q
992 Beiträge seit 2005
vor 18 Jahren

Gibt es keinen Weg, irgendwie die Paint Methode eines jeden Controls aufzurufen und der das Papier als Unterlage mitzugeben?
Das wäre SUPER! Dann könnte man auch treeviews zum beispiel wunderbar drucken(dass es da noch Probleme mit sichtbar und so gibt ist mir klar, aber das kann man ja in den Griff kriegen!)

Grüße Quallo

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

http://msdn.microsoft.com/library/deu/default.asp?url=/library/DEU/dv_vbcode/html/vbtskCodeExamplePrintingForm.asp
Habe jetzt versucht das Beispiel aus VB nach C# zu übertragen, aber in VB hab ich null Wissen. Kann mir im Beispiel nicht jede Codezeile erklären. Hier mal meine Adaption. Hoffe mir kann man dabei helfen.


private void pd_PrintPage(object sender, PrintPageEventArgs e)
		{
			Graphics grfx = e.Graphics;
			Graphics g = this.CreateGraphics();
			Size s = this.Size;
			bitmap = new Bitmap(s.Width, s.Height, g);
			Graphics mg = Graphics.FromImage(bitmap);
			Graphics pgrfx = grfx;
			e.Graphics.DrawImage(bitmap,0,0);
		}

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

Ich habe kurz ein lauffähiges Sample in C# hingemalt....

Vorteil: Du kannst auch nur ein Control drucken ....


using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Printing;
using System.Runtime.InteropServices;

namespace WindowsApplication23
{
	/// <summary>
	/// Summary description for PrintScreen.
	/// </summary>
	public class PrintFunctions
	{
		public PrintFunctions()
		{
		}

		[DllImport("gdi32.dll")]
		private static extern long BitBlt(
			IntPtr hdcDest,
			int xDest,
			int yDest,
			int nWidth,
			int nHeight,
			IntPtr hdcSource,
			int xSrc,
			int ySrc,
			Int32 dwRop);

		const int SRCCOPY=13369376;
		private Image _ImageToPrint;
		/// <summary>
		/// Druckt ein Control (oder Form) 
		/// </summary>
		/// <param name="pCtrl">Das zu druckende Control</param>
		public void PrintControl(Control pCtrl)
		{
			this.PrintControl(pCtrl,null);
		}
		/// <summary>
		/// Druckt ein Control (oder Form) auf einen speziellen Drucker
		/// </summary>
		/// <param name="pCtrl">Das zu druckende Control (oder Form)</param>
		/// <param name="pPrinterName">Der Name des Druckers (z.B: aus System.Drawing.Printing.PrinterSettings.InstalledPrinters)</param>
		public void PrintControl(Control pCtrl, string pPrinterName)
		{
			//weil wir eine Variable auf Klassenebene verändern 
			//gegen andere Threads blocken
			lock(this)
			{
				//erstelle das PrintDoc
				PrintDocument doc=new PrintDocument();
				//Wenn ein PrinterName übergeben wurde ändere den Printer für dieses Doc
				if (pPrinterName!=null && pPrinterName!=string.Empty)
				{
					doc.PrinterSettings.PrinterName=pPrinterName;
				}
				//PrintPage anschnallen
				doc.PrintPage+=new PrintPageEventHandler(doc_PrintPage);

				//Quellobjekte für den Kopiervorgang erstellen
				Graphics gSource=Graphics.FromHwnd(pCtrl.Handle);
				Rectangle rectSource=pCtrl.ClientRectangle;
				_ImageToPrint=new Bitmap(rectSource.Width,rectSource.Height,gSource);

				//Source hdc erstellen
				IntPtr hdcSource=gSource.GetHdc();

				//Zielobjekte für den Kopiervorgang erstellen
				
				Graphics gTarget=Graphics.FromImage(_ImageToPrint);
				IntPtr hdcTarget=gTarget.GetHdc();

				//per BitBlt das Image vom hdcSource auf hdcTarget kopieren
				BitBlt(hdcTarget,0,0,rectSource.Width,rectSource.Height,hdcSource,0,0,SRCCOPY);

				//verwendete objekte freigeben
				gSource.ReleaseHdc(hdcSource);
				gTarget.ReleaseHdc(hdcTarget);

				//Druck synchron auslösen 
				doc.Print();

				//Druck wurde durchgeführt
				//PrintPage abschnallen
				doc.PrintPage-=new PrintPageEventHandler(doc_PrintPage);
				_ImageToPrint=null;
			}
		}
 
		/// <summary>
		/// Wird für jede zu druckende Seite aufgerufen
		/// </summary>
		/// <param name="sender">der sender</param>
		/// <param name="e">die PrintPageEventArgs, in welche das Image gepinselt werden muss</param>
		private void doc_PrintPage(object sender, PrintPageEventArgs e)
		{
			e.Graphics.DrawImage(_ImageToPrint,0,0);
		}
	}
}



Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

erst einmal nen fettes THX für die Mühe die du dir gemacht hast. Leider will es bei mir nicht laufen. Bei dieser Codezeile


//Zielobjekte für den Kopiervorgang erstellen
				_ImageToPrint=new Bitmap(rectSource.Width,rectSource.Height,gSource);

steigt der Debugger mit der Meldung:
_
Eine nicht behandelte Ausnahme des Typs 'System.InvalidOperationException' ist in system.drawing.dll aufgetreten.

Zusätzliche Informationen: Das Objekt wird zur Zeit anderswo verwendet._

aus.

Ich habe deine Klasse direkt eingebunden, will heissen: Beim entsprechenden Klick erzeuge ich eine neue Instanz, übergebe ihr die Form oder das Control mit dem Aufruf PrintFunctions.PrintControl(this);. Ich glaube nicht das es notwendig sein sollte von deiner Klasse zu erben, oder irre ich mich da?

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

Original von dschmoegner
Hallo Programmierhans,

erst einmal nen fettes THX für die Mühe die du dir gemacht hast. Leider will es bei mir nicht laufen. Bei dieser Codezeile

  
//Zielobjekte für den Kopiervorgang erstellen  
  			_ImageToPrint=new Bitmap(rectSource.Width,rectSource.Height,gSource);  
  

steigt der Debugger mit der Meldung:
_
Eine nicht behandelte Ausnahme des Typs 'System.InvalidOperationException' ist in system.drawing.dll aufgetreten.

Zusätzliche Informationen: Das Objekt wird zur Zeit anderswo verwendet._

aus.

Sorry das war mein Fehler.... hatte den ganzen Code sauber aufgebaut und dann aber zur Dokumentation die Zeilen neu geordnet (zuerst Source-Objekte dann Target-Objekte).... tja dann leider nicht mehr getestet....

Es liegt nur an der Reihenfolge der Zeilen..... habs im Originalbeitrag korrigiert

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Danke, das hat mir sehr viel weiter geholfen. Wobei mir die Sache mit Quelle und Ziel auch hätte auffallen müssen.
Die gdi32.dll, stamm die aus der MFC?

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

4.221 Beiträge seit 2005
vor 18 Jahren

gdi steht für Graphical Display Interface und ist ein BetriebssystemFile (MFC verwendet dieses auch)

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

N
4.644 Beiträge seit 2004
vor 18 Jahren

Original von Programmierhans
gdi steht für Graphical Display Interface

Nicht ganz, GDI

4.221 Beiträge seit 2005
vor 18 Jahren

Original von Noodles

Original von Programmierhans
gdi steht für Graphical Display Interface

Nicht ganz,
>

OK thx Noodles .....

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
506 Beiträge seit 2005
vor 18 Jahren

brauch ich diesen ganzen code um eine form zu printen? oder gibts da schon was einfacheres evt. mit .NET 2?

mfg

4.221 Beiträge seit 2005
vor 18 Jahren

Original von torkel
brauch ich diesen ganzen code um eine form zu printen? oder gibts da schon was einfacheres evt. mit .NET 2?

mfg

Da kriegst Du eine Lösung frei Haus geliefert.... und bist nicht mal zufrieden 🤔

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
506 Beiträge seit 2005
vor 18 Jahren

hi... dieser code ist für mich leider nicht verständlich...

wie kann ich denn sagen, dass er mir genau der inhalt dieser form zb. form2 drucken soll und wie starte ich den druck???

mfg

4.506 Beiträge seit 2004
vor 18 Jahren

Guten morgen torkel!

Als erstes: musst Du den kompletten Code verstehen?

Naja, ich hab Dir versprochen intensiver zu helfen, also...

  • Es gibt in dieser Klasse 1 öffentliche Methode, einmal überladen (PrintControl()).
  • Einmal mit dem Aufrufparameter "Control" und einmal "Control" + "spez. Drucker"
  • Beim ersten wird meines Erachtens der Standarddrucker benutzt, beim 2. benötigst Du den Druckernamen (z.B: aus System.Drawing.Printing.PrinterSettings.InstalledPrinters).
  • Die erste Überladung ruft die 2. auf mit dem zweiten Parameter = "null" -> spart doppelter Code

Dann gehts so in der Methode weiter...


                //erstelle das PrintDoc
                PrintDocument doc=new PrintDocument();
                //Wenn ein PrinterName übergeben wurde ändere den Printer für dieses Doc
                if (pPrinterName!=null && pPrinterName!=string.Empty)
                {
                    doc.PrinterSettings.PrinterName=pPrinterName;
                }

Ein Print-dokument erstellen und den Printer festlegen, bei == "null" wird Standarddrucker benutzt.


                //PrintPage anschnallen
                doc.PrintPage+=new PrintPageEventHandler(doc_PrintPage);

Eine neue Ereignisbehandlungsroutine wird hier festgelegt. Bei eintreten des Ereignises PrintPage vom Print-Dokument wird in die Methode "doc_PrintPage()" gesprungen. (Wird hier nur festgelegt, nicht ausgeführt!)


                //Quellobjekte für den Kopiervorgang erstellen
                Graphics gSource=Graphics.FromHwnd(pCtrl.Handle);
                Rectangle rectSource=pCtrl.ClientRectangle;
                _ImageToPrint=new Bitmap(rectSource.Width,rectSource.Height,gSource);

In diesen Zeilen wird direkt das Handle auf ein Control geholt und weitere Objekte wie zunächst das Rectangle und dann das Bitmap erzeugt, die im Folgenden dann noch mit Inhalt gefüllt und später dann das bmp ausgedruckt wird.

In C/C++ Zeiten konnte man das mit Pointern lösen, hier ist das etwas .NET-like angepasst.


                //Source hdc erstellen
                IntPtr hdcSource=gSource.GetHdc();

Ich vermute, dass hdc hardcopy heißen soll. Hier wird also ein Objekt "hdcSource" erstellt, das gleich mit dem Hardcopy des angegebenen Controls verknüpft wird. Hier wird meines Erachtens sozusagen wieder nur "Pointer" festgelegt, noch kein Inhalt transferiert.


               //Zielobjekte für den Kopiervorgang erstellen               
                Graphics gTarget=Graphics.FromImage(_ImageToPrint);
                IntPtr hdcTarget=gTarget.GetHdc();

Analog zu den Quellenobjekten wird hier das gleiche für die Zielobjekte gemacht.


                //per BitBlt das Image vom hdcSource auf hdcTarget kopieren    
                          BitBlt(hdcTarget,0,0,rectSource.Width,rectSource.Height,hdcSource,0,0,SRCCOPY);

HIER wird der Kopiervorgang durchgeführt in das Zielobjekt auf Bitbasis. Was die Konstante (letzter Parameter) macht weiss ich nicht, das müsste man in der Doku finden. Das ist eine Methode die zuvor per DLL-Import bekannt gemacht wurde. In den vorigen Beiträgen wurde ja erklärt, was die "gdi32.dll" ist.


                //verwendete objekte freigeben
                gSource.ReleaseHdc(hdcSource);
                gTarget.ReleaseHdc(hdcTarget);

                //Druck synchron auslösen
                doc.Print();

                //Druck wurde durchgeführt
                //PrintPage abschnallen
                doc.PrintPage-=new PrintPageEventHandler(doc_PrintPage);
                _ImageToPrint=null;

Das dürfte jetzt wieder einfach sein. Die "Pointer" also das Handle direkt auf die Objekte wieder freigeben, den Druck auslösen und anschließend dem Event-Handler die am Anfang bereitgestellte Methode wieder entziehen (auch hier bedeutet das Ressourcenfreigabe).

Wenn ich nicht falsch liege, dann wird bei "doc.Print()" auch das Ereignis ausgelöst, und springt in "doc_PrintPage()" in der dann auch der eigentliche Druck als Druck-eine-Grafik-Anweisung ausgeführt wird.

Die komplette Methode ist hierbei mit einem lock{} versehen, was dazu führt, wenn gleichzeitig dieselbe Methode aufgerufen wird, dass die Ausführungen dieser Methode immer komplett und damit nacheinander ausgeführt werden. Das ist deshalb notwendig, weil
a) Handles erzeugt werden, was dazu führt, dass diese Objekte blockiert sind, und sich ein Dead-Lock ereignen könnte, und
b) weil für die Methode "doc_PrintPage()" die Variable _ImageToPrint benutzt wird, die bei einem "gleichzeitigen" benutzen total verpfuscht werden würde.

Quintessenz:
Du bist sicherlich noch nicht so weit, dass Du solchen Code in .NET selbst schreiben kannst, wenn ich das richtig weiss hast Du erst vor kurzem mit C# angefangen. Aber Dir sind die Prinzipien von Programmierung bekannt, und kannst sicherlich etwas mit meinen Erläuterungen anfangen.

@An alle:
Bitte korrigiert mich, wenn meine Erklärungen hier falsch waren, ich bin auch (noch nicht) DER WinForms- und Controls-Programmierer, dass ich das im ersten Moment 100%ig verstanden hätte.

Ciao und gute Nacht
Norman-Timo

[EDIT⚠
Ja, jetzt hab ich viel erklärt, aber noch nicht Deine Frage beantwortet 😉

Diesen Code nach belieben in Dein Projekt einfügen.

Dann kannst Du durch aufrufen von "PrintControl(myWinForm2);" das Form2 ausdrucken. Du brauchst Dich um nix kümmern, der Rest wird erledigt...
[/EDIT]

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

4.221 Beiträge seit 2005
vor 18 Jahren

@norman_timo

Danke für's erklären... insgesamt hast Du es recht gut erklärt 👍 wenn auch im Detail nicht ganz alles korrekt war (vernachlässigbar)....

hdc ist aber keine hardcopy sondern ein

Handle auf einen Device Context

Device Context = Gerätecontext

Der Gerätekontext ist eine auf Windows GDI basierende Struktur, die eine Gruppe von grafischen Objekten und deren zugeordnete Attribute sowie die Grafikmodi definiert, die sich auf die Ausgabe auswirken.

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
4 Beiträge seit 2005
vor 18 Jahren

Hallo zusammen,

bin auch noch ein relativer Neuling in C#, und hatte auch das problem das ich eine Druckroutine gesucht habe. Bei mir ist es so, das ich als Hintergrundbild ein Formular habe, und als auszufüllende Felder in dem Formular Textboxen in die Form gesetzt habe.
Hab den oben geposteten Code in mein Projekt kopiert, klappt alles eigentlich super, bei mir druckt er nur komischweise Teile des Bildschirm mit (die Taskleiste). Vielleicht kann mir jemand erklären warum er das macht, wäre super.

LG, Dennis

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Ein Formular als Hintergrundbild? Das versteh ich net so ganz.

Dein Problem hatte ich, als ich versucht hatte das Control, für den User nicht sichtbar, zu manipulieren und dann zu drucken. Ich denke mal das hängt mit dem Fensterhandle zusammen. Wenn mich nicht alles täuscht wird es aus dem Windows Forms gewonnen aus dem der Druck angestossen wird. Controls die in anderen Windows Forms untergebracht waren konnten nicht gedruckt werden. Dies ist zumindestens meine Erfahrung.

Gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

D
4 Beiträge seit 2005
vor 18 Jahren

Hi,
vielleicht habe ich mich etwas komisch ausgedrückt. Das Fenster (Form) das ich drucken möchte bekommt von mir ein Hintergrundbild in Form eines Formulars (wie z.B. einen Antrag, Vertrag etc.). Dann setze ich Textboxen auf die Form, die die auszufüllenden Felder des 'Formulars' darstellen. Am Schluss soll dann das ganze ausgedruckt werden.

Beim Drucken dann habe ich das oben genannte Problem das er nicht nur den Inhalt der Form druckt, sondern Teile des restlichen Bildschirms gleich mit.

Grüße..

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Was übergibst der Druckmethode als Control? Dein gesammtes Programmfenster?

Ansich würd ich nach deiner Beschreibung mir eher ein Drucklayout selber bauen. Ich habe für den inneren Rahmen des Drucklayoutes die Berechnung aus Windows Programmierung mit C# von Charles Petzold verwendet. Alles was ich drucken möchte wird in Rectangles gepackt, denn damit lassen sich die einzelnen Elemente wunderbar positionieren.

Warum er bei dir den Restbildschirm mitdruckt, kann ich jetzt auf Anhieb nicht sagen.

Grüsse dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

D
4 Beiträge seit 2005
vor 18 Jahren

Habs mit verschiedenen Controls probiert. Zuerst habe ich die ganze Form übergeben. Beim zweiten Versuch habe ich alles auf ein Panel gepackt, und dann dieses Panel übergeben. Gleiches Ergebnis.

Wenn es so halt nicht klappt, muss ich mir wohl oder übel ein Drucklayout basteln, dies hier wäre halt eine sehr komfortable Variante gewesen..

Danke schon mal für die bisherige Hilfe.

4.221 Beiträge seit 2005
vor 18 Jahren

Verwendust Du ein Scale ?

Hast Du mal versucht AutoScale des Forms auszuschalten ?

Wie sieht es aus wenn Du ein leeres Form1 druckst ?

Was für eine Screen-Auflösung verwendest Du ?... schon mal mit 1024*768 probiert ?

Was für einen WindowState hat das Form wenn Du es druckst ?

Ich will Dich nicht quälen, aber versuchen herauszufinden wieso da was falsch läuft...

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

D
4 Beiträge seit 2005
vor 18 Jahren

Hi,

meine Auflösung : 1280*1024

AutoScale ist auf none.

WindowState : normal

Hab jetzt rausgefunden das er da wirklich nur Probleme macht wenn die Form größer ist als die sichtbare Fläche des Bildschirms. Dann druckt er anstatt dem verdeckten Teil der Form (der aus dem Bilschirm rausragt) den unteren Bilschirmrand. Was mich allerding ein wenig wundert.

Danke für eure Hilfe..und gequält fühle ich mich nicht, finds ja super das ihr euch so bemüht.

Gruß, Dennis

T
506 Beiträge seit 2005
vor 18 Jahren

hallo

erstmals danke für die gute beschreibung. ich verstehe es noch immer nicht ganz, aber zumindest einiges besser als vorher.

aber das mit dem aufrufen klappt noch nicht:

PrintControl(myWinForm2)

ich hab jetzt den kompletten code von programmierhans eingefügt und wollte es dann über den oben genanten code aufrufen... ging aber net.

was mache ich falsch?

greetz

4.221 Beiträge seit 2005
vor 18 Jahren

Original von torkel
ich hab jetzt den kompletten code von programmierhans eingefügt und wollte es dann über den oben genanten code aufrufen... ging aber net.

Fehlermeldung ?
Verhalten ?

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
506 Beiträge seit 2005
vor 18 Jahren

ich muss zu hause schauen... ich hab deine ganze klasse in eine bestehnder Namespace in meiner Form kopiert. da macht er keine Fehler beim kompilieren, aber ich kann es dann nicht aufrufen mit

PrintControl(From2);

da kennt er mir From2 nicht.

thanxx

4.221 Beiträge seit 2005
vor 18 Jahren

@torkel

Das hat dann aber absolut gar nichts mit meinem Code zu tun.... da hast Du eine andere Baustelle !!! 😜

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo torkel,

evtl. From2 => Form2

herbivore

4.221 Beiträge seit 2005
vor 18 Jahren

Original von herbivore

evtl. From2 => Form2

Lach herbivore.... auch ein graue Masse Patient ?

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

eher ein Fall für den Augenoptiker 🙂 Aber der Gerechtigkeit halber: Ich hatte schon mal zwei Namen, die mir der Compiler als unterschiedlich angemeckert hat, direkt untereinander kopiert und den Unterschied trotzdem nicht gesehen (in einem Namen stand aber statt einem t ein l).

herbivore

T
506 Beiträge seit 2005
vor 18 Jahren

hi... ne an dem liegt es nicht, denn meine Form heisst eh anders, habe das nur als beispiel geschrieben, dass es verständlich ist.

ich glaube ich habe den code einfach falsch platziert. ich nehme die ganze klasse in meine bestehende Form, oder ist das falsch???

4.221 Beiträge seit 2005
vor 18 Jahren

Ich hab ja im Beispiel absichtlich ne eigene Klasse gemacht

dann machst Du

PrintFunctions pf=new PrintFunctions();
pf.PrintControl(-----das was du Drucken willst)

Das kannst Du dann aus jedem Form aufrufen....

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo torkelm

mag sein, dass es dann geht, aber eine Klasse so lange zu verschieben, bis sie da steht, dass sich der Code übersetzen lässt, ist keine besonders sinnvolle Vorgehensweise. Genausowenig, wie man mit private, protected und public solange spielen sollte, bis die die Zugriffe gehen, die man gerne hätte. In der Objektorientierung sind ja absichtlich mache Zugriffe verboten.

Aber bezogen auf dein Beispiel kann ich es nicht beurteilen, weil es ja gerade darauf ankommt, was das für Klassen sind.

herbivore

T
506 Beiträge seit 2005
vor 18 Jahren

@prgrammierhans: ja, jetzt hat es geklappt! merci.

aber ich kann jetzt meine form2 nicht printen.

mit

                    

PrintFunctions pf=new PrintFunctions();
 pf.PrintControl(form2);
  

kann ich denn da nicht nur den namen der form eingeben? es geht auch nicht mit der instanz der form.

wenn ich es mit this mache, drückt er mir zwar, aber ein gemisch aus form1 und form2. ich bräuchte wirklich nur den inhalt der form, kein rahmen, nix. und auch der graue hintergrund soll nicht geprintet werden.

geht das irgendwie?

mfg

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Hi torkel,

wenn du eine gesammte Form als Control übergibst, dann druckt dir diese Klasse auch die gesammte Form. Diese Klasse ist in der Lage Controls zu drucken. Wenn du mehrere Controls einer Form drucken möchtest dann solltes du die Klasse verwenden um die einzelnen Bitmaps zu generieren und dann in der OnPrint Eventmethode im Layout zu platzieren und schlussendlich zu drucken.
Die Klasse ist erweiterbar auf mehrer Controls. Ich selber habe sie um ein weiteres Control erweitert. Des funzt also.

Wenn ich dich richtig verstanden habe willst du ein komplettes WindowsForms drucken. Von welcher Form aus stösst du den Druck an? Veranlasst du in Form1 den Druck von Form2 oder veranlasst du von Form2 aus den Druck selbiger?

Gruss
dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

T
506 Beiträge seit 2005
vor 18 Jahren

@dschoegner:

nein, eigentlich weill ich nicht die ganze Form drucken. ich will nur zb. den Inhalt eines Panels oder auch von zwei Panels drucken.

zudem möchte ich den print von der form1 starten. das heisst, ich habe auf der form1 ein button und wenn der gedrückt wird, soll mir form2 gedruckt werden.

Kann ich mit dieser Klasse auch seiteneinstellungen druchtgeben? wie gross der ausdruck werden soll, und wo er auf dem blatt angeordnet wird?

sorry für diese vielen Fragen, aber das mit dem Print ist nicht so einfach, wie ich es mir gedacht habe.

greetz

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Hi torkel,

das was du möchtest, kannst du in der OnPrint-Methode erledigen ohne die Klasse von Programmierhans zu verwenden.
Nimm das was in den Panels ist und zeichne es auf den Drucker, falls es eben nicht irgendein Grafikcontrol ist.
Ich kann dir nur das Buch Windows Programmierung in C# von Charles Petzold empfehlen. Der Druck wird dort recht ausführlich mit Beispielen erklärt.

Was mich zu einer Frage führt. Ich musste feststellen, dass bei einem Merhseitendruck bei jedem 2. Druck die Seiten überlagert werden. Genauer gesagt, habe ich im 1. Druck 14 Seiten druckt er mir beim 2. Druck die Seiten überlagert also nur 7 Seiten dann.
Irgendwie verlassen mich da grad die Geister.



		private void prndoc_PrintPage(object sender, PrintPageEventArgs e)
		{
			Graphics grfx				= e.Graphics;
			Font myFont					= new Font("Times New Roman", 10);
			Pen myPen					= new Pen(Brushes.Black);
			StringFormat strFormat		= new StringFormat();

			string path					= System.Environment.GetFolderPath(Environment.SpecialFolder.System);
			Image imgtop				= Image.FromFile(path + "\\logotop.bmp");

            //Hier folgt Generierung des Drucklayouts


			PageNumber++;

			int rows = ((int)((e.MarginBounds.Bottom - 60 - rectfNotes.Bottom +5)/sizeFTime.Height)*2);

			if(((int)this.MVToPrint.TimeToPrint.Length%rows)!=0)
			{
				//Prüfen ob eine weitere Seite gedruckt werden soll
				e.HasMorePages = PageNumber<((this.MVToPrint.TimeToPrint.Length/rows)+1);			
			}
			else
			{
				e.HasMorePages = PageNumber<(this.MVToPrint.TimeToPrint.Length/rows);				
			}


			if(!e.HasMorePages)
			{
				grfx.DrawLine(myPen,new PointF(rectfSign.Left,rectfSign.Top - 1), new PointF(e.MarginBounds.Right-5,rectfSign.Top - 1));

				grfx.DrawString("Datum, Unterschrift", myFont, Brushes.Black, rectfSign, strFormat);
				PageNumber = 0;
				NumberValues = 0;
			}
			}

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

T
506 Beiträge seit 2005
vor 18 Jahren

HI...

gibt es da irgendwo ein Codebeispiel?

was hat das buch für eine IBAN Nummer?

gruss

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Original von torkel
HI...

gibt es da irgendwo ein Codebeispiel?

was hat das buch für eine IBAN Nummer?

gruss

ISBN: 3-86063-652-9

Codebeispiele.....hmmm im Grunde verfährt man in der OnPrint genauso wie man es in der OnPaint machen würde.....sich das Graphicsobject besorgen und damit zeichnen.
Ich weiss jetzt nicht wie stark du mit der OnPaint vertraut bist, aber vielleicht solltest du dich damit noch einmal kurz auseinander setzen.

gruss
dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

B
2 Beiträge seit 2005
vor 18 Jahren

Hallo!

Habe den Code probiert.... scheint auch zu funktionieren.
Bei mir kommt jedoch immer die Fehlermeldung, "Kein Drucker installier". Habe es mit dem Document Image Writer bzw. mit einem Drucker vom Netzwerk, als Standarddrucker probiert. Jedes Mal die Fehlermeldung...

Woran liegt das? Was muss ich machen?

Danke, im voraus....

MfG Bacella

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Hi bacella,

vielleicht ein bißchen billig aber auf Anhieb fällt mir nix weiter ein:



this.prndoc	= new PrintDocument();
			this.setdlg	= new PageSetupDialog();
			this.prndlg	= new PrintDialog();

			
			this.prndlg.Document		= this.prndoc;
			this.setdlg.Document		= this.prndoc;

private void FileToPrint()
		{
			if(this.prndlg.ShowDialog() == DialogResult.OK)
			{
				this.prndoc.DocumentName = "Datenblatt";
				this.prndoc.PrintPage	+= new PrintPageEventHandler(OnPrintPage);
			
			
				this.prndoc.Print();
			}
		}


Haste das alles im Code??????

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

B
2 Beiträge seit 2005
vor 18 Jahren

Hab den Code vom Programmierhans übernommen... brauch ich das dann auch nocht.... sollte ja so auch funktionieren....

Hab keine Ahnung mit Drucken... mache es zum ersten Mal

MfG Bacella

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

JA dieser Code ist notwendig, die ersten 5 stehen bei mir im Konstruktor und die Methode rufe ich auf wenn ich drucken will.

Schau dir besser noch einmal in der MSDN die Druckerfunktionen und -optionen an. Den Code einfach zu übernehmen wird dir nur sehr kurzfristig helfen.

gruss dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

T
506 Beiträge seit 2005
vor 18 Jahren

hallo

wie kann ich den Backcolor ändern, bei einem PrintOut?

hätte gerne, dass nicht der graue hintergrund gedruckt wird, sondern nur den text auf weisem background.

und gibt es irgendwo ein tutorial für diese OnPrint-Methode?

thanxx

D
dschmoegner Themenstarter:in
280 Beiträge seit 2005
vor 18 Jahren

Hi torkel,

wie schon erwähnt kann man in der OnPrint alle Zeichnen-Operationen wie in der OnPaint Methode vornehmen.....ich weiss jetzt nicht ob es für OnPrints nen Tutorial gibt, aber für die gesammte Paintgeschichte bestimmt irgendwo. Damit kann ich dir aber leider nicht dienen.

gruss

dschmoegner

Dennie Schmögner
Dipl. Ing. Informatik / Fachrichtung Automatisierungstechnik
Microsoft Business Intelligence 2005
SharePoint Portal Server 2007

A
196 Beiträge seit 2005
vor 18 Jahren

In .NET 2.0 gibt die Methode Control.DrawToBitmap .Damit kann man auch ganz einfach ein Control drucken.
Beispiel:

Bitmap b=new Bitmap(this.textBox1.Width,this.textBox1.Height);
this.textBox1.DrawToBitmap(b, e.PageBounds);
e.Graphics.DrawImage(b, new Point(15, 50));
T
253 Beiträge seit 2006
vor 17 Jahren

Ich habe mal eine Frage zu dem schon angesprochenen Buch.
Ich programmiere mit .net 2.0 und stehe genau vor dem Problem, dass ich
ein Programm schreiben muss, dass mir Adressetiketten bedruckt.

Den Drucker ansprechen klappt nur kann ich keinen String usw. übergeben. Deshalb wollte ich wissen ob das Buch (3-86063-652-9) auch für .net 2.0 geeignet ist?

Danke schonmal.

S
8.746 Beiträge seit 2005
vor 17 Jahren

Für Ettikettendruck gibt es fertige, kommerzielle Lösungen. Wenn du im kommerziellen Umfeld programmierst, dann würde ich zum Einsatz raten. Sei mal List&Label als eines der bekanntesten Produkte genannt. Kostet zwar ein paar Euros für eine Entwicklerlizenz, ist aber allemal billiger als eine handgefrickelte Lösung.

4.221 Beiträge seit 2005
vor 17 Jahren

Original von svenson
List&Label als eines der bekanntesten Produkte genannt. Kostet zwar ein paar Euros für eine Entwicklerlizenz, ist aber allemal billiger als eine handgefrickelte Lösung.

Und läuft auch wirklich gut 👍

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
253 Beiträge seit 2006
vor 17 Jahren

naja ich habe das Programm für eine Arbeitskollegin geschrieben. Und nun möchte ich es erweitern, dass es ihr die Etiketten auf Endlospapier ausdruckt.

Sicher gibt es dafür kommerzielle Software aber damit kann ich nicht meine C# Kenntnisse erweitern und verbessern 🙂