Hatena::ブログ(Diary)

やりたくないことはやらずに済む努力をすべき RSSフィード

2009-12-22

.NET製Winフォーム上にPDFを表示する

最近の仕事で、「.NET製アプリのフォームにPDFを表示させる」というのがあった。

とりあえず調べたことをまとめておく。

環境

どうやって表示するか

ざくっと調べたところ、3つの候補が出てきた

  1. WebBrowserコントロールを利用
  2. Adobe PDF Readerを利用
  3. Adobe Acrobatx.x type Libraryを利用
WebBrowserコントロールを利用する

特筆すべきことはなにもない。

フォームデザイナ上でツールボックスから「WebBrowser」を選択して配置するのみ。

Navigateメソッドを使用してPDFファイルの表示を行う。

通常Webブラウザ上でPDFを表示する環境と全く同じことになる。

つまり、PDF表示プラグインインストールされていなければならない。

Adobe ReaderやFoxit Readerをインストールしておく。

プロセスが終了しないことがあるので、必要であれば以前のメモを参照。

.NETでPDFを開くときの注意 - やりたくないことはやらずに済む努力をすべき

Adobe PDF Readerを利用する

これも簡単。

まず、VisualStudioのデザイナ画面でツールボックスにAdobeReaderのコントロールを追加する。

右クリック→アイテムの選択→COMコンポーネントタブ→「Adobe PDF Reader」にチェック。

(実体はC:\Program Files\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll

フォームに貼りつけて準備完了。

LoadFileメソッドでPDFファイルの表示を行う。

Adobe Acrobatx.x type Libraryを利用する

この方法はAdobe Acrobatインストールが必要。

まず、参照設定でCOMコンポーネントの中からAdobe Acrobatx.x type Libraryを探して参照を追加する。


表示にはAVDocオブジェクトを使用する。こんな感じでオブジェクトを生成する。

AVDoc = CType(CreateObject("AcroExch.AVDoc"), Acrobat.CAcroAVDoc)

次に、OpenInWindowExメソッドを利用して表示する。

' ここではDocumentPanelというコントロールを配置して、その上にPDFを表示
AVDoc.OpenInWindowEx(DocPathForView, _
                     Me.DocumentPanel.Handle.ToInt32, _
                     AV_EXTERNAL_VIEW, 1, 0, PDUseNone, _
                     AVZoomFitWidth, 0, 0, 0)

ちなみに、AV_EXTERNAL_VIEW = 1, PDUseNone = 1, AVZoomFitWidth = 2。

ここらへんは、AdobeのページからSDKサンプルをダウンロードすると、VBC#のサンプルが入手できるのでそこから朴る



Acrobatを利用する際のポイントをいくつか羅列しておく

''' <summary>PDF表示領域のリサイズ</summary>
''' <remarks>自動でリサイズしないので、ここでWIN32APIを利用して大きさを調整</remarks>
Private Sub DocPanel_Resize(ByVal sender As Object, ByVal e As EventArgs) Handles DocumentPanel.Resize
    If (Me.Disposing) Then
        Throw New ObjectDisposedException(MyClass.GetType.Name, "DocPanel_Resize")
    End If
    Dim parent As Control = CType(sender, Control)                                  ' AVDocが貼り付いている親ウィンドウ
    Dim pWndChild As Int32 = Win32API.GetWindow(parent.Handle.ToInt32, GW.CHILD)    ' 親ウィンドウのハンドルからAVDocのウィンドウハンドルを取得
    If Not (pWndChild.Equals(0)) Then
        Dim r As Win32API.RECT
        Win32API.GetClientRect(parent.Handle.ToInt32, r)
        Win32API.SetWindowPos(pWndChild, HWND.TOP, 0, 0, _
                              r.Right - r.Left, _
                              r.Bottom - r.Top, _
                              SWP.NOZORDER Or SWP.NOMOVE)
    End If
End Sub

*1:もちろん無ければ生成されるが

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/foohogehoge/20091222/1261454425
リンク元