2016-03-29 18 views
6

Ho un modulo che viene stampato correttamente sul mio computer ma quando distribuisco l'applicazione su un altro computer, il modulo non si adatta alla pagina e lo sfondo del desktop appare sullo stampato documento. Le differenze principali tra le due macchine sono quelle con l'impostazione DPI al 150%. Ho modificato il ridimensionamento automatico molte volte, ma non cambia nulla. Il modulo sembra ok sullo schermo ma non viene stampato correttamente. Di seguito è riportato il codice che sto usando.Il mio modulo non viene stampato correttamente quando DPI è al 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

Perché stai cercando di stampare un modulo Web? E sei sicuro che la differenza non sia nelle impostazioni di stampa tra le due macchine? –

+0

L'utente deve compilare, salvare e stampare il modulo di Windows. Il modulo viene stampato correttamente quando il DPI è al 100% o al 125% ma non al 150%. Ho un utente con problemi di vista quindi esegue l'impostazione DPI più alta. – wsb

+0

Hai una foto di come appare la stampa fallita? – NineBerry

risposta

4

La scala dpi superiore non è (come la vecchia scala 125%) realizzato aumentando la dimensione del carattere di Windows e avere l'applicazione di gestire il ridimensionamento, ma avendo il sistema operativo fare la scala per voi. In questa modalità, il sistema operativo si basa sull'applicazione delle impostazioni dpi effettive e fa da solo ridimensiona l'applicazione quando si disegna la sua superficie.

Il risultato è che all'interno dell'applicazione, le posizioni e le dimensioni dei pixel non sono quelle reali utilizzate sullo schermo. Ma il metodo CopyFromScreen() richiede le coordinate e le dimensioni effettive dei pixel. Devi scoprire il ridimensionamento dei pixel che subisce l'applicazione e quindi applicare questo ridimensionamento alle coordinate che usi.

Ecco il codice di lavoro (il metodo getScalingFactor() è stato rubato da 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); 
      } 
     } 
    } 
}