Visual C# フォームの印刷 class

ネットで調べて3つぐらいのサイトの合成です。            8/27 修正

 

この印刷では、フォームがプリント領域よりも大きいときに用紙にピッタリ収まるように縮小しているのがポイントです。

 

使用するプリンターは [A4] サイズ用紙が利用できるものとしています。

印刷出力は通常使うプリンターを使用することになります。

 

印刷上部に日付と時刻がプリントされます。

必要ない場合は、

e.Graphics.DrawString(...);

の行をコメントにして下さい。

 

フオームは横長が基本なので、印刷は [横向き] としています。

また、カラー印刷にしています。

それらも引数として渡すようにして、その値を使うように変更すれば自由度は増すでしょう。

 

(Windows10 VisualStudio 2015 C# フォームアプリケーションで動作確認済み)

 

フォームの印刷


フォームの印刷には次のようにします。



        //--------------------------------------------------------------
        //                  印刷クラスの定義
        //--------------------------------------------------------------
       
using System;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Drawing;

namespace WindowsFormsApplication1
{
        class Print
        {
            #region プリンターの初期設定
            protected void initializePrinterSettings(System.Drawing.Printing.PrintDocument PrintDocument1)
            {
            //プリンタ名の取得
            string defaultPrinterName = PrintDocument1.PrinterSettings.PrinterName;
            PrintDocument1.DefaultPageSettings.PrinterSettings.PrinterName = defaultPrinterName;
            int paperIndex = 0;
            foreach (PaperSize ps in PrintDocument1.PrinterSettings.PaperSizes)
            {
                if (ps.PaperName.Contains("A4"))//用紙のサイズ指定
                {
                    break;
                }
                paperIndex++;
            }
            PrintDocument1.DefaultPageSettings.PaperSize =
                PrintDocument1.PrinterSettings.PaperSizes[paperIndex];        
            PrintDocument1.DefaultPageSettings.Landscape = true;          //横向きならtrue
            PrintDocument1.DefaultPageSettings.Color = true;              //カラー印刷ならtrue
            }
            #endregion

            #region 印刷イベントハンドラ  印刷時の縮小倍率の決定
            public void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
            {
                //拡大率を指定.
                float zoom = 1;
                float padding = 30;
                if (this.memoryImage.Width > e.Graphics.VisibleClipBounds.Width)
                {
                    zoom = e.Graphics.VisibleClipBounds.Width /
                        this.memoryImage.Width;
                }
                if ((this.memoryImage.Height + padding) * zoom >
                        e.Graphics.VisibleClipBounds.Height)
                {
                    zoom = e.Graphics.VisibleClipBounds.Height /
                        (this.memoryImage.Height + padding);
                }
            e.Graphics.DrawString(DateTime.Now.ToString("yyyy年MM月dd日 (dddd) tt hh時mm分ss秒"),
                                  new Font("MS UI Gothic", 8), Brushes.Black, new Point(0, 0));
            // フォントサイズは適当な値を指定して下さい。
            //EventArgsのGraphicsにデータを書き込むとそれが印刷される.
            e.Graphics.DrawImage(this.memoryImage, 0, padding,
                                                   this.memoryImage.Width * zoom,
                                                   this.memoryImage.Height * zoom);
            }
            #endregion

            #region 印刷処理
            //フォームのイメージを保存する変数
            public Bitmap memoryImage;
            /// 
            /// フォームのイメージを印刷する
            /// 
            /// イメージを印刷するフォーム
            public void PrintForm(Form frm)
            {
                //フォームのイメージを取得する
                memoryImage = CaptureControl(frm);
                //フォームのイメージを印刷する
                System.Drawing.Printing.PrintDocument PrintDocument1 =
                     new System.Drawing.Printing.PrintDocument();
                initializePrinterSettings(PrintDocument1);
                PrintDocument1.PrintPage +=
                     new System.Drawing.Printing.PrintPageEventHandler(
                     printDocument1_PrintPage);

                //printPreviewDialog1.Document = PrintDocument1;
                //PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
                //printPreviewDialog1.ShowDialog();
                PrintDocument1.Print();
                memoryImage.Dispose();
            }
            #endregion

            #region コントロールのイメージを取得する
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern bool BitBlt(IntPtr hdcDest,
                 int nXDest, int nYDest, int nWidth, int nHeight,
                 IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);

            public const int SRCCOPY = 0xCC0020;
            public Bitmap CaptureControl(Control ctrl)
            {
                Graphics g = ctrl.CreateGraphics();
                Bitmap img = new Bitmap(ctrl.ClientRectangle.Width,
                    ctrl.ClientRectangle.Height, g);
                Graphics memg = Graphics.FromImage(img);
                IntPtr dc1 = g.GetHdc();
                IntPtr dc2 = memg.GetHdc();
                BitBlt(dc2, 0, 0, img.Width, img.Height, dc1, 0, 0, SRCCOPY);
                g.ReleaseHdc(dc1);
                memg.ReleaseHdc(dc2);
                memg.Dispose();
                g.Dispose();
                return img;
            }
            #endregion

            #region PrintDocument1のPrintPageイベントハンドラ
            public void PrintDocument1_PrintPage(object sender,
                 System.Drawing.Printing.PrintPageEventArgs e)
            {
                e.Graphics.DrawImage(memoryImage, 0, 0);
            }
        #endregion
    }
}


        //--------------------------------------------------------------
        //       プロブラムで印刷ボタンがクリックされたときの処理
        //--------------------------------------------------------------
        #region Print Form
        //プロブラムで印刷ボタンがクリックされたときの処理
        private void buttonPrint_Click(object sender, EventArgs e)
        {
            ///クラスのインスタンスを作成して呼び出す。
            Print Pr = new Print();
            Pr.PrintForm(this);   //引数=フォーム名
        }
        #endregion