2016-03-29 44 views
6

我的表單在我的機器上正確打印,但是當我在另一臺機器上部署應用程序時,表單不適合頁面,桌面背景出現在打印文件。兩臺機器之間的主要區別在於其中一臺DPI設置爲150%。我多次改變了自動縮放,但沒有任何變化。窗體在屏幕上看起來不錯,但是打印不正確。以下是我正在使用的代碼。當DPI爲150%時,我的表單打印不正確

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

你爲什麼要打印網頁表單?你確定這兩臺機器之間的打印設置不同嗎? –

+0

用戶需要填寫,保存並打印Windows窗體。當DPI爲100%或125%但不是150%時,表格可以正確打印。我有一個用戶有視力問題,所以他運行的DPI設置最高。 – wsb

+0

你有沒有打印輸出失敗的照片? – NineBerry

回答

4

較高的DPI縮放不是(像老125%縮放)通過增加Windows字體大小和具有處理應用程序的縮放,而是由具有操作系統做縮放你。在這種模式下,操作系統在應用程序中關於實際的dpi設置,並在繪製其表面時自行縮放應用程序。

結果是,在您的應用程序中,像素位置和大小不是屏幕上使用的真實像素位置和大小。但是CopyFromScreen()方法需要實際的像素座標和大小。您需要找出應用程序經歷的像素縮放比例,然後將此縮放比例應用於您使用的座標。

這裏是工作代碼(從this answer被盜的getScalingFactor()方法)。

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