2016-03-29 13 views
6

Ich habe ein Formular, das korrekt auf meinem Computer druckt, aber wenn ich die Anwendung auf einem anderen Computer bereitstellen, passt das Formular nicht auf die Seite und der Desktophintergrund erscheint auf dem gedruckten Dokument. Der Hauptunterschied zwischen den beiden Maschinen besteht darin, dass die DPI-Einstellung bei 150% liegt. Ich habe die automatische Skalierung viele Male geändert, aber nichts ändert sich. Das Formular sieht auf dem Bildschirm gut aus, wird aber nicht korrekt gedruckt. Unten ist der Code, den ich verwende.Mein Formular wird nicht korrekt gedruckt, wenn DPI 150% ist

private void btnPrint_Click(object sender, EventArgs e) 
    { 
     CaptureScreen(); 
     printPreviewDialog1.Document = printDocument1; 
     printPreviewDialog1.ShowDialog();    
    } 

    Bitmap memoryImage; 

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

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

Warum versuchen Sie ein Webformular zu drucken? Und sind Sie sicher, dass der Unterschied nicht in den Druckeinstellungen zwischen den beiden Maschinen liegt? –

+0

Der Benutzer muss das Windows-Formular ausfüllen, speichern und drucken. Das Formular wird korrekt gedruckt, wenn der DPI bei 100% oder 125%, aber nicht bei 150% liegt. Ich habe einen Benutzer mit Sehproblemen, so dass er die höchste DPI-Einstellung ausführt. – wsb

+0

Haben Sie ein Bild davon, wie der fehlerhafte Ausdruck aussieht? – NineBerry

Antwort

4

Die höhere dpi-Skalierung ist nicht (wie die alte 125% Skalierung), hergestellt von der Windows-Schriftgröße zu erhöhen und mit der Anwendung der Skalierung umgehen, aber durch das Betriebssystem, das tun die Skalierung für Sie. In diesem Modus liegt das Betriebssystem für die Anwendung über die tatsächlichen dpi-Einstellungen und skaliert die Anwendung selbst beim Zeichnen ihrer Oberfläche.

Das Ergebnis ist, dass in Ihrer Anwendung die Pixelpositionen und -größen nicht die tatsächlichen sind, die auf dem Bildschirm verwendet werden. Aber die CopyFromScreen() Methode erfordert die tatsächlichen Pixel Koordinaten und Größen. Sie müssen die Pixelskalierung ermitteln, die Ihre Anwendung durchläuft, und diese Skalierung dann auf die von Ihnen verwendeten Koordinaten anwenden.

Hier ist der Arbeitscode (Die getScalingFactor() Methode wurde von this answer gestohlen).

[DllImport("gdi32.dll")] 
static extern int GetDeviceCaps(IntPtr hdc, int nIndex); 
public enum DeviceCap 
{ 
    VERTRES = 10, 
    DESKTOPVERTRES = 117, 
} 

private float getScalingFactor() 
{ 
    using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) 
    { 
     IntPtr desktop = g.GetHdc(); 
     try 
     { 
      int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES); 
      int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES); 
      float ScreenScalingFactor = (float)PhysicalScreenHeight/(float)LogicalScreenHeight; 
      return ScreenScalingFactor; 
     } 
     finally 
     { 
      g.ReleaseHdc(); 
     } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    using (Graphics myGraphics = this.CreateGraphics()) 
    { 
     var factor = getScalingFactor(); 
     Size s = new Size((int)(this.Size.Width * factor), (int)(this.Size.Height * factor)); 

     using (Bitmap memoryImage = new Bitmap(s.Width, s.Height, myGraphics)) 
     { 
      using (Graphics memoryGraphics = Graphics.FromImage(memoryImage)) 
      { 
       memoryGraphics.CopyFromScreen((int)(Location.X * factor), (int)(Location.Y * factor), 0, 0, s); 
       memoryImage.Save(@"D:\x.png", ImageFormat.Png); 
      } 
     } 
    } 
} 
Verwandte Themen