プレビュー画面のカスタマイズ

このページでは、.NET版で利用可能なプレビュー画面を独自に作成する例を紹介します。 これを応用することで、任意の機能をプレビュー画面へと追加することが可能となります。

今回の例では、PDF出力機能を追加してみます。

プレビュー画面カスタマイズのサンプル
サンプルについて
完成したサンプルが example フォルダ内に以下の名前で含まれています。 ソースコード: MyFmPrintPreview.cs, ExampleCustomPreview.cs MyFmPrintPreview.vb, ExampleCustomPreview.vb

デザイン

独自のプレビュー画面を作成する場合は、以下のコントロールをフォームに貼り付けます。 本サンプルからMyFmPrintPreviewクラスをコピーして利用するのが簡単です。

プレビュー画面デザイン

これらのコントロールは全て、systembase.report.renderer.gdi.dllにて定義されています。 また、[印刷]、[PDF出力]、[閉じる]ボタンは全て標準のButtonを利用します。

コードの編集

MyFmPrintPreview.cs|vb内のソースコードについて解説します。

任意の機能を実装する上で、必ずしもこの項の内容をすべて理解する必要はありません。 MyFmPrintPreviewクラスを必要な部分だけ修正してご利用ください。

必要に応じて、「レンダラの仕様#プレビュー画面の機能」と併せてご覧ください。

コンストラクタ

MyFmPrintPreviewクラスのコンストラクタのコードです。

  // C#
  public MyFmPrintPreview()
  {
      this.InitializeComponent();
  }
  public MyFmPrintPreview(Printer printer)
  {
      this.InitializeComponent();
      this.PrintPreview.Printer = printer;
  }
  ' VisualBasic
  Public Sub New()
      Me.InitializeComponent()
  End Sub
  Public Sub New(ByVal printer As Printer)
      Me.InitializeComponent()
      Me.PrintPreview.Printer = printer
  End Sub

コンストラクタではPrinterオブジェクトを受け取り、 PrintPreview.Printerへと代入します。 これにより、PrintPreviewコントロールは帳票のプレビューを行えるようになります。

引数なしのコンストラクタは、VisualStudioのデザイン画面が開かれる際に必要となるために用意されています。

フォームロード

フォームを開いた時に実行されるコードです。

  // C#
  private void MyFmPrintPreview_Load(object sender, EventArgs e)
  {
      using (this.PrintPreview.RenderBlock())
      {
          this.PrintPreviewPage.Init(this.PrintPreview);
          this.PrintPreviewMultiPage.Init(this.PrintPreview);
          this.PrintPreviewZoom.Init(this.PrintPreview);
          this.PrintPreviewSearch.Init(this.PrintPreview, this.PrintPreviewSearchPanel);
          // 「画面サイズに合わせて拡大/縮小」状態にします
          this.PrintPreview.AutoZoomFit = true;
      }
      this.MouseWheel += new MouseEventHandler(this.MyFmPrintPreview_MouseWheel);
  }
  ' VisualBasic
  Private Sub FmPrintPreview_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
      Using Me.PrintPreview.RenderBlock
          Me.PrintPreviewPage.Init(Me.PrintPreview)
          Me.PrintPreviewMultiPage.Init(Me.PrintPreview)
          Me.PrintPreviewZoom.Init(Me.PrintPreview)
          Me.PrintPreviewSearch.Init(Me.PrintPreview, Me.PrintPreviewSearchPanel)
          ' 「画面サイズに合わせて拡大/縮小」状態にします
          Me.PrintPreview.AutoZoomFit = True
      End Using
  End Sub

このタイミングでPrintPreviewPage, PrintPreviewMultiPage, PrintPreviewZoom, PrintPreviewSearchコントロールの Initメソッドを呼ぶことで、それぞれ利用可能になります。

続いて、PrintPreview.AutoZoomFitプロパティをTrueに設定することで、 画面を開いた時点で「画面サイズに合わせて拡大/縮小」状態になるようにします。 この部分のコードによって、起動時のズーム状態を制御できます。 例えば、PrintPreview.AutoFitWidthプロパティに書き換えることで、 「画面幅に合わせて拡大・縮小」状態とすることができます。

簡略化のために、標準プレビュー画面のFmPrintPreviewが持っている StartUpZoomFit / StartUpZoomFitWidth プロパティは、 このクラス内には用意されていません。

マウスホイール操作

マウスホイールを操作した場合のコードです。

  // C#
  private void MyFmPrintPreview_MouseWheel(object sender, MouseEventArgs e)
  {
      Boolean handled = false;
      if (System.Object.ReferenceEquals(this.ActiveControl, this.PrintPreviewPage)){
          handled = this.PrintPreviewPage.HandleMouseWheelEvent(e);
      }else if (System.Object.ReferenceEquals(this.ActiveControl , this.PrintPreviewZoom)){
          handled = this.PrintPreviewZoom.HandleMouseWheelEvent(e);
      }
      if (!handled)
      {
          this.PrintPreview.HandleMouseWheelEvent(e);
      }
  }
  ' VisualBasic
  Private Sub FmPrintPreview_MouseWheel(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseWheel
      Dim handled As Boolean = False
      If Me.ActiveControl Is Me.PrintPreviewPage Then
          handled = Me.PrintPreviewPage.HandleMouseWheelEvent(e)
      ElseIf Me.ActiveControl Is Me.PrintPreviewZoom Then
          handled = Me.PrintPreviewZoom.HandleMouseWheelEvent(e)
      End If
      If Not handled Then
          Me.PrintPreview.HandleMouseWheelEvent(e)
      End If
  End Sub

PrintPreviewPageがフォーカスを得ているならばページ移動を行い、 PrintPreviewZoomがフォーカスを得ているならば拡大・縮小を行います。 それ以外の場合は、Ctrlキーが押されていれば拡大・縮小、 そうでなければページ移動を行います。

これらの処理は、各コントロールに用意されているHandleMouseWheelEventメソッドを呼ぶことで適切に実行されるので、 ここでは、どのコントロールがフォーカスを得ているかによって振り分けを行います。

キー押下

キーボードのキーが押された場合のコードです。

  // C#
  private void MyFmPrintPreview_KeyDown(object sender, KeyEventArgs e)
  {
      switch (e.KeyCode)
      {
          case Keys.P:
              if (e.Modifiers == Keys.Control)
              {
                  this.Print();
              }
              break;
          case Keys.Escape:
              if (this.PrintPreviewSearchPanel.Visible)
              {
                  this.PrintPreviewSearch.PanelHide();
              }
              else
              {
                  this.Close();
              }
              break;
          default:
              this.PrintPreview.HandleKeyDownEvent(e);
              break;
      }
  }
  ' VisualBasic
  Private Sub FmPrintPreview_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles Me.KeyDown
      Select Case e.KeyCode
          Case Keys.P
              If e.Modifiers = Keys.Control Then
                  Me.Print()
              End If
          Case Keys.Escape
              If Me.PrintPreviewSearchPanel.Visible Then
                  Me.PrintPreviewSearch.PanelHide()
              Else
                  Me.Close()
              End If
          Case Else
              Me.PrintPreview.HandleKeyDownEvent(e)
      End Select
  End Sub  

Ctrl+Pキーで印刷実行。ESCキーで検索パネルまたはプレビュー画面を閉じます。

他のキーが押されたら、PrintPreview.HandleKeyDownEventメソッドに処理を任せます。 このメソッド内で、[PageUp/Down]キーや[Home/End]キーによるページ移動が行われます。

印刷実行

印刷を実行するためのコードです。「印刷」ボタン押下によって呼ばれます。

  // C#
  public void Print()
  {
      if (this.PrintPreview.Printer.PrintDialog.ShowDialog() == DialogResult.OK)
      {
          this.PrintPreview.Printer.PrintDocument.Print();
          this.PrintExecuted = true;
      }
  }
  ' VisualBasic
  Public Sub Print()
      If Me.PrintPreview.Printer.PrintDialog.ShowDialog = DialogResult.OK Then
          Me.PrintPreview.Printer.PrintDocument.Print()
          Me.PrintExecuted = True
      End If
  End Sub  

印刷ダイアログを表示し、[印刷]ボタンが押されたらPrinter.PrintDocument.Printメソッドを呼んで印刷を行います。

印刷が行われた場合、PrintExecuted変数の値をTrueとします。 これで、プレビュー画面を呼び出すプログラムは、 この変数の値を参照することで、実際に印刷が行われたかどうかを確認することができます。

PDF出力実行

PDFファイルを出力するコードです。「PDF出力」ボタン押下によって呼ばれます。

標準のプレビュー画面であるFmPrintPreviwにはない機能です。 このコードと「PDF出力」ボタンを削除することで、 標準のFmPrintPreviewと同等のプレビュー画面とすることができます。

  // C#
  public void ExportPDF()
  {
      SaveFileDialog fd = new SaveFileDialog();
      fd.AddExtension = true;
      fd.Filter = "PDFファイル(*.pdf)|*.pdf";
      if (fd.ShowDialog() == DialogResult.OK)
      {
          try
          {
              using(FileStream fs = new FileStream(fd.FileName, FileMode.Create))
              {
                  PdfRenderer renderer = new PdfRenderer(fs);
                  renderer.Setting.ReplaceBackslashToYen = true;
                  this.PrintPreview.Printer.Pages.Render(renderer);
              }
              MessageBox.Show(fd.FileName + "を保存しました", "確認");
          }
          catch (Exception)
          {
              MessageBox.Show(fd.FileName + "の保存に失敗しました", "確認");
          }
      }
  }
  ' VisualBasic
  Public Sub ExportPDF()
      With New SaveFileDialog()
          .AddExtension = True
          .Filter = "PDFファイル(*.pdf)|*.pdf"
          If .ShowDialog = DialogResult.OK Then
              Try
                  Using fs As New FileStream(.FileName, IO.FileMode.Create)
                      Dim renderer As New PdfRenderer(fs)
                      renderer.Setting.ReplaceBackslashToYen = True
                      Me.PrintPreview.Printer.Pages.Render(renderer)
                  End Using
                  MessageBox.Show(.FileName & "を保存しました", "確認")
              Catch ex As Exception
                  MessageBox.Show(.FileName & "の保存に失敗しました", "確認")
              End Try
          End If
      End With
  End Sub  

保存するファイル名をユーザに選択してもらうためのダイアログを表示し、 「保存」ボタンが押されたらPDFを出力します。

このコードをビルドまたは実行するには、PDF出力のためのDLL参照が必要となります。 「プログラム開発の準備」ページを参照して、設定を行ってください。

プレビュー画面の表示

MyFmPrintPreviewを利用してプレビュー画面を表示するコードです。

  ' VisualBasic
  Dim printer As New Printer(pages)
  ' カスタマイズされたプレビュー画面を表示します
  Dim preview As New MyFmPrintPreview(printer)
  preview.ShowDialog()
  // C#
  Printer printer = new Printer(pages);
  // カスタマイズされたプレビュー画面を表示します
  MyFmPrintPreview preview = new MyFmPrintPreview(printer);
  preview.ShowDialog();  

コンストラクタにPrinterオブジェクトを渡し、ShowDialogメソッドを呼びます。