2016-03-29 38 views
6

Mam formularz, który drukuje poprawnie na moim komputerze, ale kiedy wdrażam aplikację na innym komputerze, formularz nie mieści się na stronie, a tło pulpitu pojawia się na wydrukowanym dokument. Podstawową różnicą między tymi dwoma maszynami jest to, że ma się ustawienie DPI na poziomie 150%. Zmieniłem automatyczne skalowanie wiele razy, ale nic się nie zmienia. Formularz wygląda dobrze na ekranie, ale po prostu nie drukuje poprawnie. Poniżej znajduje się kod, którego używam.Moja forma nie drukuje poprawnie, gdy DPI jest 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

Dlaczego próbujesz wydrukować formularz internetowy? I czy jesteś pewien, że różnica nie leży w ustawieniach drukowania między tymi dwoma maszynami? –

+0

Użytkownik musi wypełnić, zapisać i wydrukować formularz Windows. Formularz jest drukowany poprawnie, gdy DPI wynosi 100% lub 125%, ale nie 150%. Mam jednego użytkownika z problemami ze wzrokiem, więc on uruchamia najwyższe ustawienie DPI. – wsb

+0

Czy masz obraz tego, jak wygląda wydruk zakończony niepowodzeniem? – NineBerry

Odpowiedz

4

Im wyższa skalowania DPI nie jest (jak stary skalowanie 125%) przez zwiększenie rozmiaru czcionki systemu Windows i mające zastosowanie uchwyt skalowania, ale poprzez system operacyjny zrobić skalowanie dla Ciebie. W tym trybie system operacyjny znajduje zastosowanie do rzeczywistych ustawień dpi i sam skaluje aplikację podczas rysowania jej powierzchni.

Powoduje to, że w aplikacji nie są używane rzeczywiste położenia na ekranie. Jednak metoda CopyFromScreen() wymaga rzeczywistych współrzędnych i rozmiarów pikseli. Musisz dowiedzieć się, jak zmienia się piksel aplikacji, a następnie zastosować to skalowanie do współrzędnych, których używasz.

Oto działający kod (metoda getScalingFactor() została skradziona z this answer).

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