Laden...

Drucken eines Controls?

Erstellt von dschmoegner vor 18 Jahren Letzter Beitrag vor 13 Jahren 83.632 Views
Z
1 Beiträge seit 2006
vor 17 Jahren
Auflösung änderbar?!

Hallo,
hab mich auch mal an dem Code vergriffen und diesen bei mir eingebaut.
Funktioniert soweit auch alles super.
Hab nur leider das Problem, dass die erstellte Grafik (ausgehend vom Control-Handle) nur eine Auflösung von 96dpi hat. Daher sieht der Ausdruck nicht wirklich schick aus.

Gibt es eine Möglichkeit die dpi-Zahl anzupassen um bessere Druckergebnisse zu erziehlen?

4.221 Beiträge seit 2005
vor 17 Jahren

Im Prinzip ist es ein partieller PrintScreen... und der Screen hat nun mal nur 96 dpi.... man könnte das Bild zwar vergrössern... dann sind aber trotzdem nicht mehr Informationen drin.... wird also nicht besser aussehen.

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

B
26 Beiträge seit 2006
vor 17 Jahren
Problem bei der Position

Kann mir bitte jemand folgende Programmzeile erklären. Welche Koordinaten sind für die Druckposition verantwortlich? ?(

BitBlt(hdcTarget,0,0,rectSource.Width,rectSource.Height,hdcSource,0,0,SRCCOPY);

Danke erstmals!
Buck

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Buck,

das ist eine Frage für die Doku: BitBlt

herbivore

Z
47 Beiträge seit 2006
vor 17 Jahren

hallo,

erstmal n riesen dankeschön für diesen code (und erklärungen dazu), habs auch ohne probleme zum laufen gebracht. aber ich hab da jetz noch zwei problemchen bzw. anpassungen die ich gerne verwenden würde.

und zwar wie bekommt man es hin, ein control das größer ist als eine DIN A4 seite auf die papiergröße anzupassen so dass quasi dass control automatisch auf die gesamte seiten größe angepasst wird?(unter Berücksichtung der seitenränder,wie in meiner nächsten frage erklärt)

die andere frage ist, wie kann ich der methode (bzw. klasse) meine pagesetupdialog einstellungen übergeben? also was bis jetzt klappt, ist dass die einstellung der Orientierung (Hoch/Querformat) des pagesetupdialog für den druck mit der Methode übernimmt, jedoch nicht die seitenränder. das control setzt er immer ins linke obere eck. wie kann ich die seitenränder an die methode von programmierhans übergeben?

Z
47 Beiträge seit 2006
vor 17 Jahren

ist meine Frage zu trivial oder hat sie einfach noch keiner gelesen?
bräucht bitte eure hilfe.

was ich jetzt noch festgestellt habe ist wenn ich das control bzw. die form maximiert ist dann ist die auflösung zu groß und das control wird dann natürlich auf dem papier abgeschnitten. also wäre es notwendig, dass sich die druckgröße kontrollieren kann, standardmäßig würde es reichen wenn es automatisch an die papiergröße angepasst wird. ist das zu realisieren? könnt ihr mir bitte sagen wie ich das hinbekomme?
vielen dank!!

4.506 Beiträge seit 2004
vor 17 Jahren

Hallo zipperle,

na eventuell siehst Du den Wald vor lauter Bäumen wirklich nicht 😉

Dir liegt doch das Bitmap

_ImageToPrint=new Bitmap(rectSource.Width,rectSource.Height,gSource);

vor, das zum Drucker gesendet wird.

Skalier es durch ganz herkömmliche Bildtransformation, bevor Du es an den Drucker sendest. Wie das geht, solltest Du selbst herausfinden können (ich weiß es aus dem Stehgreif nicht).

Gruß
Norman-Timo

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

Z
47 Beiträge seit 2006
vor 17 Jahren

he norman, danke dir! naja das problem is net den wald nicht zu sehen sondern sich im wald zurechtzufinden, wenn man erst seit einigen wochen mit c# zu tun hat. und des druckthema is dann für so n fortgeschrittenen anfänger wie mich 😉 net so einfach. kann mir unter deinem vorschlag noch nix genaues vorstelle aber ich werd jetz ma versuchen was zu deinem vorschlag zu finden und einzulesen. evtl meld ich mich nochmal.

Z
47 Beiträge seit 2006
vor 17 Jahren

also hab des jetzt mal mit folgender methode probiert:


private Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
{  
   Bitmap result = new Bitmap(nWidth, nHeight);  
   using(Graphics g = Graphics.FromImage((Image) result)) 
   g.DrawImage(b, 0, 0, nWidth, nHeight);
   return result;
}

aber so funktioniert des irgendwie net. muss ich da noch was anderes im code ändern. also irgendwann nach meinem methodenaufruf? oder is des schon der völlig falsche weg was ich da vor hab?

den parameter b hab ich mit _ImageToPrint übergeben und die andern beiden parameter hardcodiert. da muss ich mir noch überlegen wie ich meine papiergröße bzw papiergröße minus ränder übergebe. müsste eigtl irgendwie über mein PageSetupDialog gehen !?

4.221 Beiträge seit 2005
vor 17 Jahren

@zipperle

Verwende doch den GetThumbNail aus dem folgenden Code.

Listbox für Bilder

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

Z
47 Beiträge seit 2006
vor 17 Jahren

vielen dank für die hilfe.

versuch jetzt schon den ganzen vormittag zu verstehen was da in der GetThumbnail Methode passiert, bin dann anscheinend doch noch zu sehr anfänger.
ich poste mal hjer die methode und versuch die mal zu erklären, hoff du/ihr kannst mich dann korrigieren wenn ich was falsch verstanden habe:


private Image GetThumbnail(Image pImage, Rectangle pBounds)
        {
            Image ret=new Bitmap(pBounds.Width,pBounds.Height);
            Graphics g=Graphics.FromImage(ret);
            g.FillRectangle(new SolidBrush(Color.White),0,0,ret.Width,ret.Height);
            
            float factor=Math.Max((float)pImage.Width/(float)pBounds.Width,(float)pImage.Height/(float)pBounds.Height);
            g.DrawImage(pImage,0,0,(float)pImage.Width/factor,(float)pImage.Height/factor);
            g.Dispose();
            
            return ret;
        }

  1. zunächst übergebe ich mit pImage mein bild (also das image meines controls),dass ich quasi resizen möchte!?

  2. zu übergabeparameter pBounds: das müsste mein DIN A4 blatt abzüglich der seitenränder, also die zu druckende fläche sein!??

  3. dann erzeuget man eine neue Bitmap mit den abmessungen des zu druckenden Bereichs.

  4. danach wird eine neue zeichenfläche mit den abmessungen der bitmap erstellt!?

  5. das rechteck dieser zeichenfläche wird mit weisser farbe gefüllt und mit den abmessungen der bitmap!?

  6. der factor wird benötigt um mein bild pImage auf die größe des zu druckenden bereichs zu resizen!??

  7. das resizen macht dann letztendlich die drawimage methode!??

  8. dann wird er speicher für g bereinigt.

  9. return ret; versteh ich nicht wirklich. ich will doch eigtl jetzt mein neues pImage zurückgeben. mit ret passiert doch die ganze zeit gar nichts außer in den ersten zwei zeilen. was bezweckt man damit ret zurückzugeben??

sorry für diese komischen fragen, aber nur mit der doku bin ich jetz net weitergekommen.

4.221 Beiträge seit 2005
vor 17 Jahren

Original von zipperle

  
private Image GetThumbnail(Image pImage, Rectangle pBounds)  
        {  
            Image ret=new Bitmap(pBounds.Width,pBounds.Height);  
            Graphics g=Graphics.FromImage(ret);  
            g.FillRectangle(new SolidBrush(Color.White),0,0,ret.Width,ret.Height);  
              
            float factor=Math.Max((float)pImage.Width/(float)pBounds.Width,(float)pImage.Height/(float)pBounds.Height);  
            g.DrawImage(pImage,0,0,(float)pImage.Width/factor,(float)pImage.Height/factor);  
            g.Dispose();  
              
            return ret;  
        }  
  
  1. zunächst übergebe ich mit pImage mein bild (also das image meines controls),dass ich quasi resizen möchte!?

--> ja

  1. zu übergabeparameter pBounds: das müsste mein DIN A4 blatt abzüglich der seitenränder, also die zu druckende fläche sein!??

--> ja

  1. dann erzeuget man eine neue Bitmap mit den abmessungen des zu druckenden Bereichs.

--> ja

  1. danach wird eine neue zeichenfläche mit den abmessungen der bitmap erstellt!?

--> ja

  1. das rechteck dieser zeichenfläche wird mit weisser farbe gefüllt und mit den abmessungen der bitmap!?

--> mit der Grösse des Zielbitmaps

  1. der factor wird benötigt um mein bild pImage auf die größe des zu druckenden bereichs zu resizen!??

--> ja

  1. das resizen macht dann letztendlich die drawimage methode!??

--> ja

  1. dann wird er speicher für g bereinigt.

--> ja

  1. return ret; versteh ich nicht wirklich. ich will doch eigtl jetzt mein neues pImage zurückgeben. mit ret passiert doch die ganze zeit gar nichts außer in den ersten zwei zeilen. was bezweckt man damit ret zurückzugeben??

sorry für diese komischen fragen, aber nur mit der doku bin ich jetz net weitergekommen.

Beim Punkt 9:

Graphics g ist im Prinzip die Zeichenfläche (welche auf dem ret basiert)... somit wird alles was in g gepinselt wird au das Image gepinselt.

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

Z
47 Beiträge seit 2006
vor 17 Jahren

vielen dank für die schnelle antwort und super hilfsbereitschaft. also ich denk ich müssts kapiert haben und versuch des mal gscheit in die printcontrol methode zu implementieren.

Z
47 Beiträge seit 2006
vor 17 Jahren

also irgendwie bekomm ich das nicht hin, dass er mir mein bild neu zeichnet.
er zeichnet nur das hardopy des controls in seiner ursprünglichen größe.
was mir beim debuggen aufgefallen ist, dass er trotz der division durch den factor, die höhe und breite des bildes nicht neu berechnet.
habe die printcontrol klasse auf meine bedürfnisse angepasst und poste sie mal hier vielleicht sieht ja jemand was ich da falsch mache.


public class ChartPrinting
	{
		public PrintDocument printDocument;
		private Image targetImage;
		private Image sourceImage;

		private int iControlWidth;
		private int iControlHeight;

		private float factor;

		public ChartPrinting()
		{
			this.printDocument = new PrintDocument();
			this.printDocument.DocumentName = "Einzelwertstatistik";			
		}

		[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;
		

		/// <summary>
		/// Prints a Control (or Form).
		/// </summary>
		/// <param name="pCtrl"></param>
		/// <param name="pageSettings"></param>
		public void PrintControl(Control pCtrl, PageSettings pageSettings)
		{
			this.PrintControl(pCtrl, pageSettings, null);
		}
		/// <summary>
		/// Prints a Control (or Form) to a specific printer
		/// </summary>
		/// <param name="pCtrl">Control (or Form) to print</param>
		/// <param name="pPrinterName">Name of the printer (e.g.: from System.Drawing.Printing.PrinterSettings.InstalledPrinters)</param>
		public void PrintControl(Control pCtrl, PageSettings pageSettings, string pPrinterName)
		{
			//
			// lock against other threads, due to changing a variable on class level 
			//
			lock(this)
			{
				//
				// Change printer, if a printer name was passed for this print documnet
				//
				if (pPrinterName != null && pPrinterName != string.Empty)
				{
					this.printDocument.PrinterSettings.PrinterName = pPrinterName;
				}
				//
				// Append PrintPageEventHandler
				//
				this.printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);
				//
				// Create source objects for copy process
				//
				Graphics gSource = Graphics.FromHwnd(pCtrl.Handle);
				Rectangle rectSource = pCtrl.ClientRectangle;
				this.sourceImage = new Bitmap(rectSource.Width, rectSource.Height, gSource);
				//rectSource.Size = pageSettings.PaperSize;
				//
				// Calculate print area
				//
				iControlWidth = pageSettings.PaperSize.Width - (pageSettings.Margins.Right + pageSettings.Margins.Left);
				iControlHeight = pageSettings.PaperSize.Height - (pageSettings.Margins.Bottom + pageSettings.Margins.Top);
				//
				// Create target objects with size of the print area
				//
				this.targetImage = new Bitmap(this.iControlWidth, this.iControlHeight);
				Graphics gTarget = Graphics.FromImage(this.targetImage);
				gTarget.FillRectangle(new SolidBrush(Color.White), 0, 0, this.targetImage.Width, this.targetImage.Height);
				//
				// Calculate resize factor
				//
				this.factor = Math.Max((float)this.sourceImage.Width / (float)this.iControlWidth, (float)this.sourceImage.Height / (float)this.iControlHeight);
				//
				// Draw resized Image
				//
				gTarget.DrawImage(this.sourceImage, 0, 0, (float)this.sourceImage.Width / this.factor, (float)this.sourceImage.Height / this.factor);
			
//				_ImageToPrint = this.ResizeBitmap(tempBitmap, iControlWidth, iControlHeight);
				//
				// Create source for HDC (Handle Device Context)
				//
				IntPtr hdcSource = gSource.GetHdc();
				//
				// Create destination objects for copy process
        //        
//				Graphics gTarget = Graphics.FromImage(_ImageToPrint);
				//gTarget = Graphics.FromImage(this.sourceImage);
				IntPtr hdcTarget = gTarget.GetHdc();
				//
				// Copy per BitBlt(Bit Block Transfer) the image of hdcSource to hdcTarget
				//
				BitBlt(hdcTarget, pageSettings.Margins.Left, pageSettings.Margins.Top, this.targetImage.Width, this.targetImage.Height, hdcSource, 0, 0, SRCCOPY);
				//BitBlt(hdcTarget, pageSettings.Margins.Left, pageSettings.Margins.Top, iControlWidth, iControlHeight, hdcSource, 0, 0, SRCCOPY);				
				//
				// Release used objects
				//
				gSource.ReleaseHdc(hdcSource);
				gTarget.ReleaseHdc(hdcTarget);
				//
				// Execute print synchronously
				//
				this.printDocument.Print();
				//
				// Print accomplished, release PrintPage
				//
				this.printDocument.PrintPage -= new PrintPageEventHandler(this.printDocument_PrintPage);
				this.targetImage = null;
				this.sourceImage = null;
			}
		}

		/// <summary>
		/// Will be executed for every page to print
		/// </summary>
		/// <param name="sender">The sender</param>
		/// <param name="e">PrintPageEventArgs, in which the image has to be painted</param>
		private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
		{			
			e.Graphics.DrawImage(this.targetImage, 0, 0);
		}
	}

noch eine frage zu meiner BitBlt funktion. ist es überhaupt richtig für den 2. und 3. paramter den linken und oberen seitenrad meines blattes anzugeben?

hab grad nochmal nachgeschaut, bezüglich der BitBlt und der seitenränder. 2. und 3. parameter muss auf 0 belassen werden.
dafür in e.Graphics.DrawImage(this.targetImage, 0, 0) der printDocument_PrintPage methode abändern in e.Graphics.DrawImage(this.targetImage, e.PageSettings.Margins.Left, e.PageSettings.Margins.Top).
korrigiert mich wenn des falsch is. der ausdruck scheint zumindest zu stimmen.

aber des eigentliche problem mit dem resize is leider noch net gelöst.

Z
47 Beiträge seit 2006
vor 17 Jahren

ich komm net weiter, langsam wirds frustrieren.
hat denn niemand n tipp?

F
10.010 Beiträge seit 2004
vor 17 Jahren

Meinst Du nicht, das Du die Zeit besser in eine Reporting Lösung inverstieren solltest?

Da wäre der Ausdruck jetzt schon lange fertig, und du würdest nicht mit solchen Krücken arbeiten.

4.221 Beiträge seit 2005
vor 17 Jahren

Original von FZelle
Meinst Du nicht, das Du die Zeit besser in eine Reporting Lösung inverstieren solltest?

Da wäre der Ausdruck jetzt schon lange fertig, und du würdest nicht mit solchen Krücken arbeiten.

Die "Krücke" war auch aus meiner Sicht nie für ein professionelles Reporting gedacht... Sondern nur als Quick und Dirty Printscreening auf den Drucker.

Ich kann List & Labels empfehlen... läuft stabil und ist echt flexibel (und nein ich kriege keine Provisionen!)

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

Z
47 Beiträge seit 2006
vor 17 Jahren

also gleich n komplett neue reporting lösung zu kaufen nur um einen ausdruck auf ne seitgröße anzupassen kann glaub auch nicht sonderlich wirtschaftlich sein.

naja, aber trotzdem tut er nicht wie ich will. ich find den fehler net. ich muss des bis nächste woche hinbekommen, da is abgabe meiner diplomarbeit. also ich wäre für jeden tipp dankbar. hat ja mit programmierhans seiner lösung schon ganz gut geklappt bis hier her.

4.221 Beiträge seit 2005
vor 17 Jahren

Also im ursprünglichen Code von mir wird mit


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

der Druckvorgang gestartet (und somit das Image in this.targetImage gedruckt).

Ich habe Dir die Methode genannt durch welches Du das Image auf den gewünschten Size vergrössern kannst.

also machst Du ganz einfach


this.targetImage=GetThumbnail(this.targetImage, RectangleDesPrintBereiches)

Kann so schwer doch gar nicht sein.

Code zu kopieren ist das eine... ihn auch zu verstehen das andere 8)

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

F
10.010 Beiträge seit 2004
vor 17 Jahren

Wieso Kaufen?

Es gibt die zu hauf kostenlos z.B. bei codeproject.com , sf.net, oder codeplex.com.

Und MS hat auch noch den ReportViewer ( http://www.gotreportviewer.com ) kostenlos im angebot.

Und bei MS gibt es für die, die garnichts davon halten auch noch ein PrintForm Lib.
http://msdn2.microsoft.com/en-us/vbasic/aa701261.aspx

Also warum dann soetwas selber friemeln?

J
3.331 Beiträge seit 2006
vor 17 Jahren

Zur ursprünglichen Frage: ein beliebiges Control drucken

Das Verfahren, das in dieser Diskussion hauptsächlich besprochen wurde, scheint mir viel zu umfangreich zu sein. Ich habe deshalb - ausgehend von einem "Gewusst wie" in der MSDN-Library - eine einfache Klasse erstellt, in der mit einem einfachen Aufruf ein Formular oder ein Control gedruckt oder gespeichert werden kann:

//  zum Drucken des aktuellen Formulars:
JThomas.Tools.FormPrint.Execute(this);
//  zum Drucken eines anderen Formulars, das natürlich keine NullReference sein darf:
JThomas.Tools.FormPrint.Execute(Form2);
//  zum Drucken eines beliebigen Controls:
JThomas.Tools.FormPrint.Execute(this.GroupBox3);
//  zum Speichern des aktuellen Formulars z.B. im PNG-Format im Programmverzeichnis:
JThomas.Tools.FormPrint.Execute(this,
    System.Drawing.Imaging.ImageFormat.Png,
    System.IO.Path.Combine( System.IO.Path.GetDirectoryName
        (Application.ExecutablePath),
        this.Name + ".png") );

Einzelheiten unter Formular (WinForm) drucken oder als Bitmap speichern.

Viel Erfolg! Jürgen

B
249 Beiträge seit 2005
vor 17 Jahren
Scrollbare UserControls ganzer Bereich drucken

Ich bin so frei und hab noch eine Frage zu dem Problem.

Die Methode GetBitmap von genannten JThomas.Tools.FormPrint soll ja angeblich in Version 2 vom Framework genutzt werden.
Allerdings wird bei mir da ein Bitmap erzeugt, welches nur den Rand des Controls draufhat, innerhalb ist es quasi leer. Im Anhang seht ihr was ich meine. An was kann das liegen?
Wenn ich über die alte Methode von .Net 1.1 gehe, dann gehts.

Eigentlich die wichtigere Frage ist die, die jetzt kommt 😉. Weil diese stellt sich mit beiden GetBitmap Methoden.
Wie kriege ich ein Graphics vom ganzen Control, also auch wenn dieses ein UserControl ist mit dem Flag AutoScroll = true?

J
3.331 Beiträge seit 2006
vor 17 Jahren

Hallo bubblez,

Original von bubblez
Die Methode GetBitmap von genannten JThomas.Tools.FormPrint soll ja angeblich in Version 2 vom Framework genutzt werden.
Allerdings wird bei mir da ein Bitmap erzeugt, welches nur den Rand des Controls draufhat, innerhalb ist es quasi leer. Im Anhang seht ihr was ich meine. An was kann das liegen?
Wenn ich über die alte Methode von .Net 1.1 gehe, dann gehts.

Für mich sieht das wie der Ausdruck aus dem Acrobat Reader heraus aus. So hatte ich meine Klasse gar nicht geschrieben, sondern so, dass eine Control-Instanz übergeben wird. Wie genau bist Du vorgegangen, d.h. wie hast Du meine FormPrint-Klasse aufgerufen (mit dem falschen Ergebnis)?

Original von bubblez
Eigentlich die wichtigere Frage ist die, die jetzt kommt Augenzwinkern... Wie kriege ich ein Graphics vom ganzen Control, also auch wenn dieses ein UserControl ist mit dem Flag AutoScroll = true?

Ich gebe dazu, dass ich nicht alle möglichen Controls ausprobiert habe. Ich werde mir UserControls mit AutoScroll gezielt vornehmen. Ich könnte mir vorstellen, dass der Rand der Bitmap angepasst werden muss (wie bei NET 1.1 die Titelzeile des Formulars).

Gruß Jürgen

@Moderatoren
Sollte diese Diskussion nicht besser unter Formular/Control drucken oder als Bitmap speichern fortgesetzt werden?

B
249 Beiträge seit 2005
vor 17 Jahren
X
95 Beiträge seit 2006
vor 17 Jahren

ich übergebe der klasse ein panel..

das wird auch wunderbar gedruckt...

wie kann ich denn den ausdruck auf mehrere seiten verteilen, wenn es nicht auf eine passt...????

momentan teste ich diese variante


 void printButton1_Click(object sender, EventArgs e)
        {
            CaptureScreen();
            printDocument1.Print();
        }


        Bitmap memoryImage;

        private void CaptureScreen()
        {
            Graphics myGraphics = this.CreateGraphics();
            Size s = this.panel1.Size;
            memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
            Graphics memoryGraphics = Graphics.FromImage(memoryImage);
            memoryGraphics.CopyFromScreen(this.Location.X+300, this.Location.Y, 0, 0, s);
        }

        private void printDocument1_PrintPage(System.Object sender,
               System.Drawing.Printing.PrintPageEventArgs e)
        {
            e.Graphics.DrawImage(memoryImage, 0, 0);
        }

hier könnte ich den eingelesenen bereich immer verschieben und neu rauskopieren...ist aber nicht sehr elegant...

J
3.331 Beiträge seit 2006
vor 17 Jahren

Hallo XXL,

ich gebe zu, das ist nicht sehr elegant. Bei meiner Lösung
Formular/Control drucken oder als Bitmap speichern
(siehe Hinweis von bubblez) habe ich genau auf ein solches Verfahren verzichtet, sondern stattdessen die Kompression auf Seitengröße eingebaut.

Für Dein Ziel fällt mir kein besseres Verfahren ein als das von Dir skizzierte. Du könntest es (vor allem wenn Du es häufiger benötigst) wie folgt verbessern:1.Erzeuge eine Graphics-Instanz des gesamten Controls (z.B. Panel) - das hast Du ja vorgesehen. 1.Benutze beim Document die PrintPageEventArgs.HasMorePages-Eigenschaft. 1.Registriere intern den in einer Seite bereits gedruckten Bereich. 1.Verändere beim Druck der nächsten Seite den benötigten Bereich des Graphics. 1.Kopiere den betreffenden Bereich in das aktuelle Bitmap.

Für Details verweise ich auf den Quelltext in o.g. Link, den Du entsprechend anpassen könntest.

Viel Erfolg! Jürgen

L
254 Beiträge seit 2005
vor 17 Jahren

Hallo Zusammen

Wir hatten bei uns in der Firma sehr ähnliche Probleme mit einem Grid eines Fremdkomponenten-Herstellers.

Grid hat aufm Bildschirm toll ausgesehen. Wenn mans mit dem Verfahren wie hier beschrieben gedruckt wird, sind irgendwie die inneren Elemente im Grid selbst nicht richtig gezeichnet worden, so glaub z.B. Icons und Grafiken etc.

Einer unserer Entwickler hat dann festgestellt, dass wenn er dieses "vorbereitete" PrintDocument nimmt und ins PrintPreviewControl steckt, er die Grafik vom PrintPreviewControl abgreifen kann, und diese dann wiederum Printet ^^.

Mag auf den ersten Moment total be*****ert klingen, funzt aber. (Was ich gehört habe).

Ich kann leider hier nicht n ausfühlichen Vortrag schreiben weil ich eigentlich Arbeite. Da ich aber von diesem Forum schon profitiert habe möchte ich wenigstens den groben Weg aufzeigen.

Den Quellcode habe ich leider nicht selbst geschrieben, daher müsste ich nen zweiten Entwickler belasten...

Grob ist es aber wirklich nur so, dass man das vom PrintPreview erzeugte Bild abfreift und nochmals auf die gleiche Art printet. @Edit Ich glaube das Graphics Objekt braucht man, macht aber nen unterschied ob man es direkt druckt oder per printpreview.

Wie gesagt, er hat es mir nur erzählt, ich habs nicht selbst implementiert.

Über die MSDN und das Inet müsste das relativ einfach nachzubilden sein. Wenn ihr es nicht nachvollziehen könnt, würde ich dann den Entwickler explizit um den Code und den Ablauf bitten.

Wenn es aber geht wäre ich froh wenn ihr es zuerst "selbst" probiert.
Wir drucken mit dieser Methode im Moment allerlei komplexe WinControls (Grids, Trees etc).

Gruss

Lex

@Edit: Der andere Entwickler und ich wollten eigentlich n Codereview machen, sollte das zustande kommen würde ich dann ne "richtige" Lösung hier posten....

If you can't make it, fake it.

D
6 Beiträge seit 2006
vor 16 Jahren

Hi Programmierhans,

deine Lösung wäre geradezu der Hit für mich gewesen. Allerdings taucht bei mir auch ein Problem auf, das hier schonangesprochen wurde, aber noch nicht beantwortet wurde. Vllcht hast du eine Idee?

Nochmal konkreter, wo es bei mir klemmt.

Früher habe ich unter C auch recht viel mit hWnds und hDCs um mich geschmissen 😄. Gemerkt hatte ich ir, dass die mehr oder weniger virtuell liefen, sprich, das, was ich zwischen denen hin und her kopiere hat nicht viel damit zu tun, ob ich die involvierten Handles in einem Control habe, welches gerade auf dem Screen zu sehen ist.
Ein Beispiel, ich erzeuge eine Bitmap in einem Form ausserhalb des sichtbaren Bereichs. Sagen wir auch, die Form ist wesentlich größer als die Bildschirmausflösung.
Deseiteren ginge ich hin und erzeige eine Bitmap im Speicher.

Habe ich früher munter mit BitBlt u.ä. Teile oder komplett durch die Gegend kopiert, so hat das hervorragend funktioniert.

Hier, und da komme ich auf deinen Code zurück (nur das das klar ist, dein Code ist nicht das Problem, sondern das, was beim BitBlt darin passiert), gibt es nur noch Murks. In der Tat sieht es so aus, als würde immer zwangsweise, mehr oder minder Irgendwas das Controls, das sich im sichtbaren Bereich befindet, geblittet. Noch schwachsinniger wird es, wenn ich jede Codezeile debuge, denn dann bekommt die Zielbitmap auf jeden Fall immer einen schönen Codeausschnitt den ich gerade debugge verpasst. Kann ich mir dann auch ausdrucken <g>.

Wenn ich sonst was zu dem Problem gefunden hätte, hätte ich gesagt, das muss ein MS bug sein 🙂, aber mich dünkt, es ist doch irgendwo hier in der Ecke zwischen den Ohren zu suchen. 🙂

Das Thema ist ja jetzt schon was her, weissst du, oder jemand anderes dazu inzwischen mehr? Das macht mich quasi wahnsinnig 🙂

viele Grüße,

dietmar


Edited: Ich probiers nochmal sachlicher 🙂

Gegeben sei eine Form von Größe z.B. 2000*2000.
Auf der Form befindet sich irgendwas graphisches egal mit welchen Controls.
Die Startkoordinate der Form soll ausserhalb des sichtbaren Bereichs liegen.

Erzeuge ich nun ein Image im Speicher und BitBlt'e es komplett in das Speicerimage, so befindet sich darin irgendwas, meist aus dem sichtbaren Bereich. Nicht jedoch einfach die Kopie des grossen, nicht sichtbaren hDCs. (das ist das hier in dem thread schon angesprochene Problem. Es hat gar nichts mit dem Mapping auf den Drucker zu tun, sondern das Problem passiert schon vorher. So als ob Windows nicht mehr in der Lage sei, die ....gnah... virtuellen Inhalte eines Fensters korrekt Bitmapseitig zu verwalten, was früher mit MS C kein Problem war.)

Die involvierten HDCs und WindowsHandle sind gecheckt, die sind alle korrekt!

Wenn ich das Beispiel abwandle und das gegebene Form in einer Dimension von z.B. 100*100 an einer sichtbaren Stelle positioniere, so verhält sich das zwar besser aber immer noch nicht richtig. Beispiel, vor dem ausdruck gebe ich noch eine Msgbox mit der Handlenummer aus, welche auf dem form liegt. Dann ist das Zielimage zwar gefüllt mit dem Inhalt des Fenstern, jedoch ist auch die MSgBox mitgeblittet und das ist echt völliger Schwachsinn, weil die nicht zum Handlekontext des Formhandles gehört. (die Msgbox liefert ein eigenes handle zurück).
Es sieht ein bischen so aus, als ignoriere Windows komplett jeglichen Versuch ein valides Windowshandle zu übergeben, sondern orientiere sich ausschliesslich immer am Devicecontext des Screens.

Da geht also was eklatant schief. Ist das jemandem bekannt, oder hat er mit ähnlichem rumgehampelt und eine Lösung gefunden? Solange das nicht gelöst ist, kann die hier vorgestellte, wirklich sehr sehr schöne und slicke Drucklösung nicht verlässlich funktionieren ohne üble Tricks zu verwenden. Nu bin ich aber soweit, das ich das bräuchte. Also: Help! 🙂

viele Grüße,

Dietmar


edited2: Ich probiers mal mit Code. Zugrunde liegt ein Projekt, dass deine Quelle PrintFunctions enthält. Desweitern gibt eine Form Form1, auf die schlicht ein WebBrowser und ein Button geploppt werden. Der WebBrowser extended automatisch auf die Größe des Containerfenster (Eigenschaft Dock=Fill). Das wars an Vorbereitung. Den TestCode habe ich auf ein Minimum zusammengestrippt.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace webctrlprint
{
	public partial class Form1 : Form
	{
		Uri uri;
		PrintFunctions oPrn = new PrintFunctions();

		public Form1()
		{
			InitializeComponent();
			
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			this.uri = new Uri("http://www.google.de");
			this.webBrowser1.Url = this.uri;
			this.Left=0;
			this.Width=1280;
			this.Height=800;
			this.Top=750;

		}

		private void button1_Click(object sender, EventArgs e)
		{
		
			System.Threading.Thread.Sleep(2000);
			oPrn.PrintControl(this.webBrowser1);
			MessageBox.Show("Killerbox");

		}

	}
}


Wenn du das laufen läßt siehst du das Fenster mit der Googlestartseite, aber nur den obersten Teil, der Rest des Fensters ist halt nach unten rausgeschoben. Nun klicke auf den Button (den ich direkt unter die Titelzeile geklemmt habe, um den Druck zu initiieren.

Du wirst (hoffe ich doch <g>) allerlei Quark auf deiner Bitmap finden, u.a. zwar das Google Banner, aber eben auch z.B. die Taskleiste und ähnliche Ungereimtheiten.

Bin quasi am Ende mit meinem Latein, habe sogar schon mit den RasterOps rumprobiert <g>, aber nun geht mir langsam der Stoff aus. Ich hänge eben an dem Umstand das ich 'das Gefühl' habe, BitBlt machts unter C# nur irgendwie Screenbezogen, während ich von früher weiss, das das wirklich sch..egal war, was auch sinn macht. Ich gehe davon aus, das es immer noch so ist, und ich irgendwo den Kardinaldreher drin habe.
PS: Mein Standarddrucker ist Win2PDF, so dass ich das Ergebnis sofort sehe und nicht physisch ausdrucken muss.


edited3: Gestern ist mir die Fragestellung nochmal andersrum eingefallen 🙂 :
Was nützt mir die Übergabe eines eindeutigen WindowHandles (also die Zuordnung eines eindeutigen graphischen Kontextes), wenn der mehr oder weniger bei der Kernoperation BitBlt() ignoriert zu werden scheint?

So sieht das für mich jedenfalls aus. Ich streite ja gar nicht ab, das ich eventuell im Basisverständnis einen Dreher habe, aber wo ist dieser 🙂 ?

4.221 Beiträge seit 2005
vor 16 Jahren

Hallo dietmar_bos

Leider kann ich nicht mehr tun als dir bestätigen dass ich das Verhalten auch genau so erlebt habe wie du es schilderst.

Gruss
Programmierhans

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

F
10.010 Beiträge seit 2004
vor 16 Jahren

Ein weiterer Grund darüber nachzudenken, das anders zu implmentieren.

Eine Bitmap zum drucken zu benutzen ist da würde ich sagen Suboptimal.
Zumal es von MS ja auch 2 "neue" libs zum drucken gibt.

Vielleicht hilft ja auch der Ansatz von
http://www.codeproject.com/dotnet/PrintingFormReport.asp

D
6 Beiträge seit 2006
vor 16 Jahren

Hi Programmierhans,

Original von Programmierhans
Leider kann ich nicht mehr tun als dir bestätigen dass ich das Verhalten auch genau so erlebt habe wie du es schilderst.

kaum zu glauben, soll es echt ein MS Bug sein? Die haben das zwar drauf bugs zu produzieren, aber bei den essentials, waren die bisher eigentlich immer verlässlich. Dann ist BitBlt ja nun nicht gerade eine Exotenfunktion, da hätte ich mit mehr Rumoren genereller Natur gerechnet, aber so dick was entdecken kann man zu dem Thema nicht im Netz.

Naja, schönen Dank schonmal. Ändert auch nichts daran, dass ich dein Codesnippet wirklich gut finde. Wenn BitBlt mal gehen sollte 🙂 werde ich's bestimmt nochmal verwenden 🙂.

Schönes Wochenende und Danke.

Dietmar

D
6 Beiträge seit 2006
vor 16 Jahren

Hi FZelle,

Original von FZelle
Ein weiterer Grund darüber nachzudenken, das anders zu implmentieren.

Ah was! 🙂

Im Ernst, wie immer im geschundenen Programmiererleben haperts an der Zeit. Das Thema drucken ist bei uns an einer Stelle ein recht diffiziles Thema. Im Rahmen einer 'Abschaffung des Problems' 🙂 müssen wir recht schnell Vollzug melden können. Ich bin noch nicht mal sicher, ob die Ausgabequalität gereicht hätte, aber das Wagnis wäre ich eingegangen, zumal die involvierten Komponenten genau zu diesem Thema wieder reichlich Schalterchen und Methoden liefern, die man da gar icht vermutet hätte.

Allein der Zeitmangel wird dau führen, das wir das Thema jetzt nicht weiterverfolgen. Es wäre aber eine schicke Sache gewesen das benutzen zu können, weil man eben keine selbstaufbereitete Druckausgabe mehr gebraucht hätte.

Lange Rede kurzer Sinn, es stehen 2 Alternativen an, die wir uns gerne geklemmt hätten, weil Sie eben mit Sicherheit mehr Zeit benötigen werden, als die hier diskutierte Lösung benötigt hätte.

>> http://www.codeproject.com/dotnet/PrintingFormReport.asp<<

Das werde ich mir aber auf jeden Fall mal ansehen. Besten Dank für den Tip.

Dietmar


edited: den Link habe ich mir angesehen. Das ist eine gute Idee, mir aber noch nicht ansatzweise ausgebaut genug. Dennoch etwas, das man weiter entwickeln kann. für die Zukunft sicher eine gute Idee. Bei uns gehts konkret darum, aus einer gerenderten Webseite ein PDF zu erzeugen und dieses auch zeitgleich zum Ausdruck zu bringen. Der Ausdruck soll sowohl lokal, im Netz, als auch unter Citrix Bedingungen möglich sein. Das ist schon eine wirklich üble Kombo, die aber gerade mit der so einfachen und genialen Lösung von Programmierhannes 🙂 im Ansatz durchführbar gewesen wäre. Die Überführung in PDF ist eher kein Problem damit und darüber hinaus trägt die Verwendung von PrintDocument die Möglichkeit der Ansprache eines dezidierten Druckers in sich, was für uns ebenfalls Bonus wäre. Bisher lief es übers WebControl, der nur auf Standarddrucker geht. Die Alternative, den Standarddrucker vor dem Druck dann eben einstellen zu müssen, macht es uns aber in der schon erwähnten 'dreifaltigen' Druckumgebung, denn das haut nicht durchgängig hin. (Stichwort hier ist Citrix, welches eine Diva sein kann 🙂)
Dies nur zur Info. Wir werden es wahrscheinlich mit eine PDFLib und eines AddOns für den Ausdruck der selben jetzt lösen. Erste Tests waren ganz erbaulich, legen aber leider noch relativ viel Änderungsaufwand als Hürde mit auf den Weg. Wäre halt mit der Idee hier schon gewesen.

P
992 Beiträge seit 2007
vor 16 Jahren

Hallo,

wie kann ich denn ein Control Drucken, welches nicht komplett sichtbar ist.
Mit DrawToBitmap bekomme ich ja nur den sichtabren Bereich.

Ich habe ein Form, in diesem befindet sich ein Panel und dieses Panel enthält zwei treeViews und zahlreiche selbstgezeichnete Elemente. Ich möchte nun diese Grafik ausdrucken. Sie ist aber eben größer als der sichtbare Bereich.

Hat jemand eine Idee oder ein Link?

Danke!

3.825 Beiträge seit 2006
vor 16 Jahren

Hallo,

kann man den Code von Programmierhans von Seite 1 dieses Theads so ändern dass ein Windowsform mit Rahmen und Titel und Close-Button gedruckt wird ?

Den neuen Befehl WindowsForm1.DrawToBitmap(..) kann ich nicht verwenden da ich das Control mit geöffnetem Menutrip drucken will und DrawToBitmap das aktuell geöffnete Menü erstmal schließt.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

630 Beiträge seit 2007
vor 16 Jahren
Etwas Offtopic

Hallo Leute,

Alle die Reporting (selber) machen wollen (Rechnungen, Listen, Quittungen etc.) sollten sich vieleicht überlegen ein Template in HTML und CSS zu erstellen und es anschließend mit Variablen zu garnieren. In etwa so:


<html>
 <head><title>[HEADER] - [PAGE_HEADER]</title></head>
  <body>
   <h1>[HEADER]</h1>
   <h2>[PAGE_HEADER]</h2>
   <p>[CONTENT]</p>
   <small>[PAGEFOOTER]</small>
   <small><center><i>Page [PAGE_NUMBER]</i></center></small>
  </body>
</html>

Anschließend könnte man die Variablen mit einfachem String.Replace() durch den Inhalt ersetzen. Gedruckt wird über das Webbrowser Control.

Der Vorteil ist das man dank CSS Positionierungen in Millimeter und Zentimeter Vornehmen kann. Auch der PDF-Export dürfte so um einiges leichter fallen.

Vieleicht bastele ich, wenn ich etwas Zeit habe mal ein kleines Framework. Ansonsten währe es ja eine tolle Projektidee für Leute die etwas üben wollen. 😉

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

F
10.010 Beiträge seit 2004
vor 16 Jahren

Es gibt bei codeproject bereits so ein projekt.

J
3.331 Beiträge seit 2006
vor 16 Jahren

Original von BerndFfm
kann man den Code von Programmierhans von Seite 1 dieses Theads so ändern dass ein Windowsform mit Rahmen und Titel und Close-Button gedruckt wird ?

Hallo Bernd,

schau Dir einmal meine Lösung Formular/Control drucken oder als Bitmap speichern an, ob Du damit etwas anfangen kannst. Ich benutze zwar DrawToBitmap und hatte es noch nicht mit ToolStrips probiert; aber ein "altes Menü" konnte dadurch gedruckt werden, dass der Aufruf von FormPrint in diesem Menü enthalten war.

Gruß Jürgen

3.825 Beiträge seit 2006
vor 16 Jahren

Hallo Jürgen,

Deine Lösung benutze ich schon, die ist echt genial !

Der Anwender kann nun in meiner Applikation an jeder Stelle einen Printscreen machen und diesen speichern, drucken oder per Email versenden.

Dabei ist es natürlich erwünscht dass ein aufgeklapptes Menü zugeht.

Für das Handbuch aber möchte ich die Menüs aufgeklappt lassen. Einige Leute lesen das Handbuch ohne die Applikation geöffnet zu haben. Deswegen habe ich bei jeder Erklärung eines Menüs dieses als Printscreen dabei.

Für diesen Zweck nutze ich jetzt die Lösung von Programmierhans, ohne Rahmen, aber mit Menü !

Dank nochmal an euch beide für die Mühe die ihr euch damit gemacht habt.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

B
204 Beiträge seit 2006
vor 16 Jahren

Hallo!

Nachdem ich stundenlang versucht habe mehrere Panels untereinander zu drucken (keine Ahnung wieso das nicht geht, habs mit drawtobitmap usw. versucht) bin ich auf diesen Beitrag gestoßen.

Mit der Methode printcontrol hat das super funktioniert.
Aber ich würde gern mehrere Panels drucken (auf einer seite)
hab gelesen, dass das mit diese methode funktioniert, weiß aber nicht wie...

bitte um hilfe...

mfg
budiq160

D
39 Beiträge seit 2007
vor 15 Jahren
Ausdruck nur schwarz

Hallo zusammen,

ProgrammierHans danke viel mal für die PrintFunctions-Klasse. Läuft "eigentlich" super. Nur ich hab ein Problem und zwar möchte ich gerne eine Form ausdrucken (PDF-Drucker), aber wenn ich das tue erhalte ich nur ein schwarzes Viereck im Ziel-PDF.

Es liegt allerdings nicht am PDF-Drucker, denn ich habe den Ausdruck ebenfall an einem physischen Drucker ausprobiert. Gleiches Ergebnis 🙁 Wisst vielleicht an welcher Form-Eigenschaft das liegt? Mit einer neu erstellten Form geht es nämlich ohne Probleme..

MfG Diggler

WTF ist ein Constructor?! 👶

4.221 Beiträge seit 2005
vor 15 Jahren

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

D
39 Beiträge seit 2007
vor 15 Jahren

Danke vielmals! Leider läufts aber immer noch nicht ganz richtig, denn wenn ich jetzt drucke wird nur der Fensterrahmen abgedruckt anstatt die Komponenten ohne Rahmen..

?(

WTF ist ein Constructor?! 👶

R
258 Beiträge seit 2007
vor 15 Jahren

@Diggler:
Bei mir gehts ganz einfach mit "PrintFunktions.PrintControl(this)".
Das druckt den Inhalt des Fensters ohne den Rahmen.

Ich habe auch ein paar kleinere Änderungen vorgenommen:

                doc.DefaultPageSettings.Landscape = true; //Querformat, meine Anwendung ist Breit :)

                doc.DocumentName = pCtrl.Name +" "+ DateTime.Now.ToString();// Dokumentenname wird angezeigt als:
                //Form1 08.08.2008 11:11:11 oder so ähnlich :)
                
                gTarget.DrawString(DateTime.Now.ToString(),new Font("Arial",16), Brushes.Black, new PointF(0,0));
                //Zusätzlich wird das Datum und die Uhrzeit in die obere linke Ecke geschrieben, wo bei mir zufällig noch Platz war.

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

Fügt in den Dokumententitel und in die obere linke Ecke des Ausdrucks Datum und Uhrzeit ein. Ausserdem ist meine Anwendung zu breit, deswegen habe ich auf Querformat umgestellt(Blöde Landscape-Eigenschaft, nicht nur, dass man auf "Landscape" nur durch Zufall kommt, nein, dass "true" für Querformat steht, kommt man auch nur durch probieren oder msdn raus -.-).

Ich hab auch mal schnell ein PDF angehängt mit einem Ausdruck.

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

16 Beiträge seit 2010
vor 13 Jahren

Hallo zusammen!

Vorerst möchte ich sagen: Vielen Dank für die Beiträge, tipps, etc!
Alles super hilfreich!

Um mich allerding auch den Fragenstellern anzuschließen, folgendes Problem:
Ich drucke eine Form (orientiert an Programmierhans' Code(s.1)).
Das funzt soweit einwandfrei!
hab auch verstanden, das ich bei

Graphics Source = new Graphics.FromHwnd(<zu druckendes Control>);

ein zu druckendes Control wählen kann.

allerdings habe ich 2 Controls die aneinander hängen und die auch auf dem Papier so ausgedruckt werden sollen...

Wenn ich allerdings diese Prozedur wie sie Programmierhans beschrieben hat auf jedes Control anwende dann überschneiden die sich doch beim Druck gegenseitig, oder bin ich da auf dem Holzweg??

Hat jemand nen Tipp/Hinweis wie ich das Problem lösen könnte??

Danke schonmal!

Grüße maddn

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo maddn,

hast du schon probiert, beide Controls auf ein Panel zu packen und dann das Panel als zu druckendes Control anzugeben?

herbivore

16 Beiträge seit 2010
vor 13 Jahren

funktioniert!

hm... is ne sache, auf die man selbst kommen KÖNNTE... 🤔
sorry!

aber jetzt die master frage: ?(

Geht das auch irgendwie mit 2 verschiedenen Forms??
Da gibts ja nicht irgendeinen geimeinsamen Container (wie das Panel)...

Oder bleibt mir da nix anderes übrig, als nen kompletten screenshot zu drucken?

Danke!

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo maddn,

auch zwei Forms kann man auf ein Panel packen, wenn man TopLevel auf false setzt.

herbivore

4.221 Beiträge seit 2005
vor 13 Jahren

Pack die zwei Forms einfach auf ein weiteres Form / Panel...

Ein Form ist ja auch nur ein Control... man muss dann einfach noch ein Property auf dem Form setzen... ich glaube es war TopLevel=false... oder so ähnlich

Gruss
Programmierhans

Edit: Argh herbivore war mal wieder schneller

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

16 Beiträge seit 2010
vor 13 Jahren

Hm okay... mir wurde bei gebracht, das man die Form und die enthaltenen Controls zumindest ein bisschen auseinander halten soll...
Aber anscheinend darf man heute garnixmehr glauben was einem begebracht wird!

Ich hab jetzt ein Panel angelegt, in das 2 Forms eingefügt werden.
Leider wird das Fenster beim Button_Click nicht mehr angezeigt, wenn ich dessen Property "Formx.topLevel =false;" setze?

So siehts roh aus:


Form1 f1; 
Form2 f2;  //Wird direkt rechts an Form1 gehängt
Panel p = new Panel();

private void btn_Form1_Click(object sender, System.EventArgs e)
{
    f1= new Form1();
    f1.TopLevel=false;
    p.Controls.Add(f1);
    f1.Show();
}
private void btn_Form2_Click(object sender, System.EventArgs e)
{
    f2= new Form2();
    f2.TopLevel=false;
    p.Controls.Add(f2);
    f2.Show();
}

So solltes richtig sein, oder??
Bin leider mit Forms nicht so vertraut... X(
Bitte korrigiert mich wenn ich totalo aufm falschen dampfer bin.

Jedenfalls: sobald ich Toplevel auf false setz, werden die Forms nichtmehr angezeigt...

Danke euch!

4.221 Beiträge seit 2005
vor 13 Jahren

Spiel mal mit der Reihenfolge der Befehle

.Show
.TopLevel=false
.Controls.Add

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