2016-03-29 12 views
6

Formum düzgün yazdırılıyor, ancak makinemde düzgün yazdırılan bir form var ancak uygulamayı başka bir makineye dağıttığımda, form sayfaya sığmıyor ve masaüstü arka planı yazdırılan sayfada görünüyor belgesi. İki makine arasındaki birincil farklar, DPI ayarının% 150'de olmasıdır. Otomatik ölçeklemeyi birçok kez değiştirdim ama hiçbir şey değişmiyor. Form ekranda iyi görünüyor, ancak doğru yazdırmıyor. Kullanmakta olduğum kod aşağıdadır.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

Neden bir web formu yazdırmaya çalışıyorsunuz? Farkın, iki makine arasındaki baskı ayarlarında olmadığından emin misiniz? –

+0

Kullanıcı, Windows formunu doldurmalı, kaydetmeli ve yazdırmalıdır. DPI,% 100 veya% 125 olduğunda ancak% 150'de olmadığında form doğru şekilde yazdırılır. Görme sorunları olan bir kullanıcım var, bu yüzden en yüksek DPI ayarını çalıştırıyor. – wsb

+0

Hatalı çıktının nasıl göründüğüne dair bir resminiz var mı? – NineBerry

cevap

4

yüksek dpi ölçekleme (eski 125% ölçekleme gibi) Windows yazı tipi boyutunu artırarak ve uygulama ölçeklendirme ele alarak yapılmış, ancak sizin için ölçeklendirme yapmak işletim sistemini alarak değil. Bu modda, işletim sistemi gerçek dpi ayarları ile ilgili uygulamaya dayanır ve kendi yüzeyini çizerken uygulamayı kendi başına ölçeklendirir.

Sonuç, uygulamanızın içinde piksel konumlarının ve boyutlarının ekranda kullanılan gerçek değerler olmamasıdır. Ancak CopyFromScreen() yöntemi, gerçek piksel koordinatlarını ve boyutlarını gerektirir. Uygulamanızın ölçeklendirdiği piksel miktarını bulmanız ve ardından bu ölçeklemeyi kullandığınız koordinatlara uygulamanız gerekir.

İşte çalışma kodu (getScalingFactor() yöntemi this answer'dan çalınmış).

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