2013-10-03 58 views
6

我的程序:包含一個幾個文本框和一個按鈕的窗體。 'Default Printer'在我的計算機上設置爲Adob​​e PDF在C中打印窗體/用戶控件#

我的目標:想要在用戶單擊「打印」按鈕時截取窗體/用戶控件。屏幕截圖然後以.pdf格式保存在桌面上。

我的問題:我有以下兩個問題的代碼:

  1. 截圖的大小:截圖的尺寸過大,它不適合頁面大小(默認頁面大小)打印/轉換爲.pdf。請參考下面的兩張圖片。我希望整個屏幕截圖適合頁面內容。
  2. 詢問兩次在哪裏轉換並保存:當我點擊「打印表格」按鈕時,程序會問我TWICE在哪裏打印/轉換並保存文件。我希望程序只問我一次,在哪裏打印和保存文件。

問題1:打印時,程序捕獲的屏幕截圖不適合頁面。 Problem 1: The screenshot captured by the program does not fit the page when printed.

我想要的屏幕顯示圖像,以適應這樣.PDF的一個頁面上: enter image description here

代碼:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     button1.Text = "Print Form"; 
     button1.Click += new EventHandler(button1_Click); 
     printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage); 
     this.Controls.Add(button1); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     CaptureScreen(); 
     printDocument1.Print(); 
    } 

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

感謝您的幫助提前。我是一名新手,學習c#語言,您的幫助將非常感謝。 :)

+1

看看這個Q/A的C#圖像縮放樣本:http://stackoverflow.com/questions/249587 –

+0

對於第二個問題(雙對話框),這只是一個猜測,但嘗試刪除這一行'printDocument1 .PrintPage + = ...'從你的構造函數中。我猜這已經發生在'InitializeComponent()'裏面,這意味着你顯式地處理了兩次事件。打開你的Form1.Designer.cs文件,看看是否有其他東西你正在複製。 (除了你的Init調用在構造函數中的其他所有內容可能是多餘的。) –

+0

@PaulSasik:不。對於問題2,刪除該行會給我一個白色的PDF,並且無法保存。 ._。 – Smith

回答

3

好了,檢查了這一點,特別是修改printDocument1_PrintPage

 private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) 
     { 
      // calculate width and height scalings taking page margins into account 
      var wScale = e.MarginBounds.Width/(float)_memoryImage.Width; 
      var hScale = e.MarginBounds.Height/(float)_memoryImage.Height; 

      // choose the smaller of the two scales 
      var scale = wScale < hScale ? wScale : hScale; 

      // apply scaling to the image 
      e.Graphics.ScaleTransform(scale, scale); 

      // print to default printer's page 
      e.Graphics.DrawImage(_memoryImage, 0, 0); 
     } 

我感動了所有事件wireup到的InitializeComponent在那裏它通常應該去,但它更多地參與代碼:

using System; 
using System.Drawing; 
using System.Drawing.Printing; 
using System.Windows.Forms; 

namespace testScreenCapScale 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() { InitializeComponent(); } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      CaptureScreen(); 
      printDocument1.Print(); 
     } 

     private Bitmap _memoryImage; 

     private void CaptureScreen() 
     { 
      // put into using construct because Graphics objects do not 
      // get automatically disposed when leaving method scope 
      using (var myGraphics = CreateGraphics()) 
      { 
       var s = Size; 
       _memoryImage = new Bitmap(s.Width, s.Height, myGraphics); 
       using (var memoryGraphics = Graphics.FromImage(_memoryImage)) 
       { 
        memoryGraphics.CopyFromScreen(Location.X, Location.Y, 0, 0, s); 
       } 
      } 
     } 

     private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) 
     { 
      // calculate width and height scalings taking page margins into account 
      var wScale = e.MarginBounds.Width/(float)_memoryImage.Width; 
      var hScale = e.MarginBounds.Height/(float)_memoryImage.Height; 

      // choose the smaller of the two scales 
      var scale = wScale < hScale ? wScale : hScale; 

      // apply scaling to the image 
      e.Graphics.ScaleTransform(scale, scale); 

      // print to default printer's page 
      e.Graphics.DrawImage(_memoryImage, 0, 0); 
     } 
    } 
} 

Form1.Designer.cs

namespace testScreenCapScale 
{ 
    partial class Form1 
    { 
     private System.ComponentModel.IContainer components = null; 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
       components.Dispose(); 
      base.Dispose(disposing); 
     } 

     private void InitializeComponent() 
     { 
      this.printDocument1 = new System.Drawing.Printing.PrintDocument(); 
      this.button1 = new System.Windows.Forms.Button(); 
      this.SuspendLayout(); 
      // 
      // printDocument1 
      // 
      this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage); 
      // 
      // button1 
      // 
      this.button1.Location = new System.Drawing.Point(64, 220); 
      this.button1.Name = "button1"; 
      this.button1.Size = new System.Drawing.Size(75, 23); 
      this.button1.TabIndex = 0; 
      this.button1.Text = "button1"; 
      this.button1.UseVisualStyleBackColor = true; 
      this.button1.Click += new System.EventHandler(this.button1_Click); 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(384, 377); 
      this.Controls.Add(this.button1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 

     } 

     private System.Drawing.Printing.PrintDocument printDocument1; 
     private System.Windows.Forms.Button button1; 
    } 
} 
+0

非常感謝!我感謝您的幫助。我會試着去測試它。再次感謝。 :) – Smith

+0

@史密斯:就像我說的,對於初學者(快速測試),只需複製並粘貼'printDocument1_PrintPage'方法的內容即可。縮放是獨立的,沒有其他需要改變。這是涉及更多的事件處理,您可以單獨處理。 –

+0

太棒了!它起作用Paul!你真棒..再次感謝.. :) – Smith