Delphi Programming / Object Pascal
[掲載 2010年05月05日] [更新 2014年08月31日] Delphi サンプルプログラム集 |
724_Adobe Acrobat オブジェクトの操作 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro +Adobe Acrobat Pro 9.5.5
開発環境にも,実行環境にも,Adobe Acrobat が必要 |
|
724_Acrobat_TAcroApp.zip [2,300 KB] 2014年08月31日版 (EXE 同梱) |
ワードやエクセルの操作同様,Adobe Acrobat もそのオブジェクト(OLE : Adobe では IAC と言っている) を生成して操作することができます.Delphi にはこれらのオブジェクトを操作するオブジェクトは用意されていません.タイプライブラリの取り込みで必要なユニットファイルを作成します.
このページのサンプルは,開発値環境にも実行環境にも (Adobe Reader ではなく) Adobe Acrobat がインストールされていなければ動作しません.これはワードやエクセルがインストールされていなければ,基本的にはその操作ができないのと同じです.
Adobe Acrobat がインストールされていない環境での PDF 文書の操作については,リンクの [720] [07_PDF 文書の作成や操作関係の参考リンク - Adobe サイト以外] を参考にしてください.
参考リンクの [PDF VBA (Excel) から Acrobat ... ] の記事は,Acrobat SDK を解析しながら作成したそうです.折角公開していただいているので,利用しない手はありません. |
このページのサンプルを利用するには,[タイプライブラリの取り込]で,Adobe Acroabat のタイプライブラリの取り込を行い,Acrobat_TLB.pas という名前のユニットを作成します.これがコンポーネントのファイルとなります.
ここでは,このコンポーネントを Delphi にあらかじめ用意してある dclusr.dpk というパッケージに登録 (インストール) するものとします.このパッケージをまだインストールしていない場合は,インストールしておきます.
このタイプライブラリの取り込みの記事は,Delphi 2010 の操作画像です.
|
|
図1
タイプライブラリの取り込
- [コンポーネント]
- [コンポーネントのインポート]
|
|
図2
追加
- [登録済みのタイプライブラリ] にはおそらくないので [追加]で
|
|
図3
DLLまたはTLBを選択
- Acrobat.dll を選択
- Acrobat.tlb でもよい
Acrobat.tlb はタイプライブラリファイルそのもの
|
|
図4
登録パレットの選択
- 今回は [ActiveX] とした
- 存在しない名前にすると作成される
- [コンポーネントラッパーを生成する] にチェック]
- [ユニットディレクトリ] はコンポーネントのファイルが出力される場所
パスが通った場所にする
今回はデフォルトのままとした
|
|
図5
登録先パッケージ
|
|
図6
dclusr.dpk に登録
- dclusr140.pbl は,dclusr.dpk のコンパイル済のファイル名
|
|
図7
[上書き保存] [ビルド]
- [上書き保存]
- [ビルド] または [再構築]
- IDE を一度閉じて,再起動
|
Adobe Acrobat を起動して PDF 文書を表示します.表示ウィンドウの位置とサイズを指定するために,Acrobat のクラス名である AcrobatSDIWindow をウィンドウリストから検索してウィンドウハンドルを取得しています.このサンプルで設定した内容は,Acrobat の次回起動時にもこの設定が使用されます.本来は元の値を保存して,終了時は元に戻すべきでしょう.
フォームを閉じると,システムで開いている Acrobat 全てが閉じて終了となります.Button3 クリックでも Acrobat が閉じますが,システムには Acrobat.exe が残った状態となっています.
参考リンクの AcroExch.App 等はクラス識別子 (CLSID) です.
後述のように,CreateOleObject あるいは CreateComObject で PDF 関係のオブジェクトを生成する場合に使用します.
CreateOleObject または CreateComObject で PDF 関係のオブジェクトを生成した場合は,ConnectTo メソッドを実行する必要はありません.TAcroApp 等のクラスにもキャストできます.
|
|
図8
設計時画面
|
|
図9
Button1 クリック
- 表示文書は [ファイル] [プロパティ] のダイアログの [開き方] の倍率を全体表示にしてある
- これは Power Point の画面ではない
|
|
図10
頁数は 47 になっている |
|
図11
Button2 クリック
|
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Acrobat_TLB, OleServer;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
AcroApp1: TAcroApp;
AcroAVDoc1: TAcroAVDoc;
AcroPDDoc1: TAcroPDDoc;
Panel1: TPanel;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private 宣言 }
AcroHandle : Cardinal;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
//AcroAppConst.pasは同梱の定数ユニット
uses AcroAppConst;
{$R *.dfm}
//-----------------------------------------------------------------------------
// ウィンドウハンドルからウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetWindowClassNameStr(hWindow: HWND): String;
var
Buffer : array[0..MAX_PATH-1] of Char;
Len : Integer;
begin
FillChar(Buffer, SizeOf(Buffer), #0);
Len := GetClassName(hWindow, Buffer, Length(Buffer));
if Len > 0 then begin
Result := Buffer;
end else begin
Result := '';
end;
end;
//-----------------------------------------------------------------------------
// アプリのウィンドウハンドルを取得するためのEnumWindowsのコールバック関数
//
// Acrobatのトップウィンドのクラス名はAcrobatSDIWindow
// この関数はWindowsが呼出すメッセージ処理なのでTFormのメンバーにはできない
//-----------------------------------------------------------------------------
function EnumWindowsProc(hTopWnd: HWND; lp: LPARAM): BOOL; stdcall;
var
ClassName : String;
begin
Result := True;
//クラス名がAcrobatのトップウィンドウのものかクラス名で調査
//取得できたら引数のlpにその値を代入してこれ以上の列挙はしない
ClassName := GetWindowClassNameStr(hTopWnd);
if UpperCase(ClassName) = UpperCase('AcrobatSDIWindow') then begin
LPDWORD(lp)^ := hTopWnd;
Result := False;
end;
end;
//=============================================================================
// このフォームを前面に表示
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
end;
//=============================================================================
// このフォームを閉じる時はPDF文書も閉じてAcrobatを終了させる
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Button3Click(nil);
end;
//=============================================================================
// ファイル選択ダイアログを表示してPDF文書を選択
//
// ここで設定している位置サイズやメニューの表示は,Acrobatの次回起動時にも
// この設定が使用されるので,本来は元に戻しておくべき
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
PageCount : Integer;
Flag : OleVariant;
begin
with OpenDialog1 do begin
InitialDir := ExtractFileDir(ParamStr(0));
DefaultExt := 'PDF';
Filter := 'PDF|*.PDF';
Options := [ofReadOnly];
end;
if OpenDialog1.Execute then begin
Update;
AFile := OpenDialog1.FileName;
//開いているのは閉じる
AcroAVDoc1.Close(-1);
AcroAVDoc1.Open(AFile, '');
//AcroAVDoc1をTAcroAppのAVDocオブジェクトとする
AcroAVDoc1.ConnectTo(AcroApp1.GetAVDoc(0) as CAcroAVDoc);
//開いたドキュメントからPDDocオブジェクトを取得
AcroPDDoc1.ConnectTo(AcroAVDoc1.GetPDDoc as CAcroPDDoc);
//総頁数を取得して表示
PageCount := AcroPDDoc1.GetNumPages;
Panel1.Caption := '頁数 ' + IntToStr(PageCount);
AcroAVDoc1.SetTitle('Acrobat テスト Presented by Mr.XRAY');
//SetViewModeの5は本文のみの表示
AcroAVDoc1.SetViewMode(5);
//メニューバー,ツールバー,左側のツールバーも非表示にしてしまう
Flag := 0;
AcroApp1.SetPreferenceEx(avpShowMenuBar, Flag);
AcroApp1.SetPreferenceEx(avpShowToolBar, Flag);
AcroApp1.SetPreferenceEx(avpShowLeftToolBar, Flag);
//ウィンドウの列挙
//Acrobatのハンドルが取得できればAcroHandleにその値を返す
//そのハンドルを使用してPDF文書の表示位置とサイズを変更
EnumWindows(@EnumWindowsProc, LPARAM(@AcroHandle));
if AcroHandle <> 0 then begin
SetWindowPos(AcroHandle, 0, 0, 0, 800, 600, SWP_NOZORDER);
end;
//表示
AcroApp1.Show;
end;
end;
//=============================================================================
// ツールバー表示のトグル動作
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
Flag : OleVariant;
SetV : OleVariant;
begin
Flag := AcroApp1.GetPreferenceEx(avpShowToolBar);
if Flag = 'false' then begin
SetV := 1;
end else begin
SetV := 0;
end;
AcroApp1.SetPreferenceEx(avpShowToolBar, SetV);
end;
//=============================================================================
// PDF文書を閉じてAcrobatも閉じる
// このサンプルはTAcroApp等のコンポーネントを配置している
// したがって,アプリ起動時にそのインスタンスが生成される
// このアプリを終了するまでシステムのプロセスにはAcrobat.exeが残ることになる
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
begin
//下の2行はCloseAllDocsがあれば本来は不要
AcroAVDoc1.Close(1);
AcroPDDoc1.Close;
AcroApp1.CloseAllDocs;
//Acrobatの終了.必ずHideメソッドと対で使用する
AcroApp1.Hide;
AcroApp1.Exit;
end;
end.
フォームに配置した TPanel 上に PDF 文書を表示する例です.
この TPanel 上に表示する方法は,表示開始時は TPanel の Client 領域に表示されますが,フォームのサイズを変更しても表示サイズは変更されません.そこで Acrobat のウィンドウハンドルを取得して,そのウィンドウの位置とサイズをフォームの OnResize イベントで再設定しています.Acrobat を他のウィンドウ上に表示した場合のクラス名は,Amber External Window です. |
|
図12
設計時画面
- TAcroApp 関係コンポーネントを配置
- [Button1] PDF 文書を開く
- [Button2] 前のページを表示
- [Button3] 次のページを表示
- [Button4] 100 % 表示
- [Button5] 描画領域幅に合わせて表示
- [Button6] 印刷
|
|
図13
Button1 クリックしてPDF表示
- くどいようだがこれは Power Point の画面ではない
|
|
図14
Button3 で頁を進めた画面 |
|
図15
Button4 で 100% 表示 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Acrobat_TLB, OleServer;
type
TForm1 = class(TForm)
Panel1: TPanel;
AcroApp1: TAcroApp;
AcroAVDoc1: TAcroAVDoc;
AcroPDDoc1: TAcroPDDoc;
AcroAVPageView1: TAcroAVPageView;
Panel2: TPanel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Panel3: TPanel;
OpenDialog1: TOpenDialog;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormResize(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private 宣言 }
AcroHandle : Cardinal;
PageCount : Integer;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
//AcroAppConst.pasは同梱の定数ユニット
uses AcroAppConst;
{$R *.dfm}
//-----------------------------------------------------------------------------
// ウィンドウハンドルからウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetWindowClassNameStr(hWindow: HWND): String;
var
Buffer : array[0..MAX_PATH-1] of Char;
Len : Integer;
begin
FillChar(Buffer, SizeOf(Buffer), #0);
Len := GetClassName(hWindow, Buffer, Length(Buffer));
if Len > 0 then begin
Result := Buffer;
end else begin
Result := '';
end;
end;
//-----------------------------------------------------------------------------
// ウィンドウハンドルを取得するためのコールバック関数
// OpenInWindowExで表示した場合のAcrobatのクラス名はAmber External Window
// このクラス名のウィンドウを検索する
// この関数はWindowsが呼出すメッセージ処理なのでTFormのメンバーにはできない
//-----------------------------------------------------------------------------
function EnumChildWindowsProc(hWindow: HWND; lp: LPARAM): BOOL; stdcall;
var
ClassName : String;
begin
Result := True;
ClassName := GetWindowClassNameStr(hWindow);
if UpperCase(ClassName) = UpperCase('Amber External Window') then begin
//取得したハンドル値を呼出し側で使用するために,引数のlpに代入
//取得したらそれ以上の列挙は不要なのでResult := Falseにして列挙終了
LPDWORD(lp)^ := hWindow;
Result := False;
end;
end;
//=============================================================================
// PDF文書を閉じてAcrobatも閉じる
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//下の2行はCloseAllDocsがあれば本来は不要
AcroAVDoc1.Close(1);
AcroPDDoc1.Close;
AcroApp1.CloseAllDocs;
//Acrobatの終了.必ずHideメソッドと対で使用する
AcroApp1.Hide;
AcroApp1.Exit;
end;
//=============================================================================
// フォームをリサイズしたら表示しているAcrobatもリサイズ
// OpenInWindowExで表示してもリサイズは自動ではない
//=============================================================================
procedure TForm1.FormResize(Sender: TObject);
begin
if AcroHandle <> 0 then begin
SetWindowPos(AcroHandle,
0,
0,
0,
Panel1.Width,
Panel1.Height,
SWP_NOZORDER or SWP_NOMOVE );
end;
end;
//=============================================================================
// ファイル選択ダイアログを表示してPDF文書を選択
//
// ここで設定している位置サイズやメニューの表示は,Acrobatの次回起動時にも
// この設定が使用されるので,本来は元に戻しておくべき
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
PageNo : Integer;
begin
with OpenDialog1 do begin
InitialDir := ExtractFileDir(ParamStr(0));
DefaultExt := 'PDF';
Filter := 'PDF|*.PDF';
Options := [ofReadOnly];
end;
if OpenDialog1.Execute then begin
Update;
AFile := OpenDialog1.FileName;
//Panel1上にPDF文書を表示
//開いているのは閉じる
AcroAVDoc1.Close(-1);
AcroAVDoc1.OpenInWindowEx(AFile,
Panel1.Handle,
AV_PAGE_VIEW,
0,
0,
PDDontCare,
AVZoomFitPage,
100,
100,
0);
//AcroAVDoc1をTAcroAppのAVDocオブジェクトとする
AcroAVDoc1.ConnectTo(AcroApp1.GetAVDoc(0) as CAcroAVDoc);
//開いたドキュメントからPDDocオブジェクトを取得
AcroPDDoc1.ConnectTo(AcroAVDoc1.GetPDDoc as CAcroPDDoc);
//後の操作用にAcroAVPageViewオブジェクトを取得しておく
AcroAVPageView1.ConnectTo(AcroAVDoc1.GetAVPageView as CAcroAVPageView);
//現在の頁番号(最初の頁番号は0)と総頁数を取得して表示
PageNo := AcroAVPageView1.GetPageNum;
PageCount := AcroPDDoc1.GetNumPages;
Panel3.Caption := IntToStr(PageNo + 1) +' / ' + IntToStr(PageCount);
Self.Caption := AcroAVDoc1.GetTitle;
//AcrobatはPanel1上に表示しているので.このTPanelの子ウィンドウを検索し
//Panel1上のAcrobatのハンドルをAcroHandleに取得する
EnumChildWindows(Panel1.Handle, @EnumChildWindowsProc, LPARAM(@AcroHandle));
end;
end;
//=============================================================================
// 前の頁を表示
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
PageNo : Integer;
begin
if AcroPDDoc1.GetNumPages < 0 then exit;
PageNo := AcroAVPageView1.GetPageNum;
if (PageNo + 1) > 1 then begin
AcroAVPageView1.GoTo_(PageNo - 1);
Panel3.Caption := IntToStr(PageNo) +' / ' + IntToStr(PageCount);
end;
end;
//=============================================================================
// 次の頁を表示
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
PageNo : Integer;
begin
if AcroPDDoc1.GetNumPages < 0 then exit;
PageNo := AcroAVPageView1.GetPageNum;
if (PageNo + 1) < PageCount then begin
AcroAVPageView1.GoTo_(PageNo + 1);
Panel3.Caption := IntToStr(PageNo + 2) +' / ' + IntToStr(PageCount);
end;
end;
//=============================================================================
// 100%表示にする
//=============================================================================
procedure TForm1.Button4Click(Sender: TObject);
begin
if AcroPDDoc1.GetNumPages < 0 then exit;
AcroAVPageView1.ZoomTo(AVZoomNoVary, 100);
end;
//=============================================================================
// 描画領域の幅に合わせた表示にする
//=============================================================================
procedure TForm1.Button5Click(Sender: TObject);
begin
if AcroPDDoc1.GetNumPages < 0 then exit;
AcroAVPageView1.ZoomTo(AVZoomFitVisibleWidth, 0);
end;
//=============================================================================
// 印刷
// 印刷開始と終了頁が間違っていると印刷しないので注意
//
// [備考]
// Windows XP(SP3) + Delphi2010(UP5) Pro + Adobe Acrobat Pro 8.1.5
// の環境下では,印刷の際に別のAcrobatのウィンドが表示され,印刷が終了しても
// 閉じない
// 印刷メソッド実行後,AcroApp1.Hideを実行すれば閉じる(見えなくなる?)
//=============================================================================
procedure TForm1.Button6Click(Sender: TObject);
var
nFirstPage : Integer;
nLastPage : Integer;
nPSLevel : Integer;
bBinaryOk : Integer;
bShrinkToFit : Integer;
bReverse : Integer;
bFarEastFontOpt : Integer;
bEmitHalftones : Integer;
iPageOption : Integer;
begin
if AcroPDDoc1.GetNumPages < 0 then exit;
nFirstPage := 0;
nLastPage := PageCount - 1;
nPSLevel := 3;
bBinaryOk := 1;
bShrinkToFit := 0;
bReverse := 0;
bFarEastFontOpt := 0;
bEmitHalftones := 0;
iPageOption := -3;
AcroAVDoc1.PrintPagesSilentEx(nFirstPage,
nLastPage,
nPSLevel,
bBinaryOk,
bShrinkToFit,
bReverse,
bFarEastFontOpt,
bEmitHalftones,
iPageOption);
end;
end.
04_Adobe Acrobat オブジェクトの実行時 ( 動的 ) 生成 |
Acrobat 関係のオブジェクトを実行時 (動的) に生成する場合の例です.
テスト内容は最初のサンプルと同じです. |
|
図16
設計時画面 |
リスト3
Acrobat 関係オブジェクトの実行時生成 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Acrobat_TLB, OleServer;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private 宣言 }
AcroHandle : Cardinal;
AAcroApp: TAcroApp;
AAcroAVDoc: TAcroAVDoc;
AAcroPDDoc: TAcroPDDoc;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
//AcroAppConst.pasは同梱の定数ユニット
uses AcroAppConst;
{$R *.dfm}
//-----------------------------------------------------------------------------
// ウィンドウハンドルからウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetWindowClassNameStr(hWindow: HWND): String;
var
Buffer : array[0..MAX_PATH-1] of Char;
Len : Integer;
begin
FillChar(Buffer, SizeOf(Buffer), #0);
Len := GetClassName(hWindow, Buffer, Length(Buffer));
if Len > 0 then begin
Result := Buffer;
end else begin
Result := '';
end;
end;
//-----------------------------------------------------------------------------
// アプリのウィンドウハンドルを取得するためのEnumWindowsのコールバック関数
//
// Acrobatのトップウィンドのクラス名はAcrobatSDIWindow
// この関数はWindowsが呼出すメッセージ処理なのでTFormのメンバーにはできない
//-----------------------------------------------------------------------------
function EnumWindowsProc(hTopWnd: HWND; lp: LPARAM): BOOL; stdcall;
var
ClassName : String;
begin
Result := True;
//クラス名がAcrobatのトップウィンドウのものかクラス名で調査
//取得できたら引数のlpにその値を代入してこれ以上の列挙はしない
ClassName := GetWindowClassNameStr(hTopWnd);
if UpperCase(ClassName) = UpperCase('AcrobatSDIWindow') then begin
LPDWORD(lp)^ := hTopWnd;
Result := False;
end;
end;
//=============================================================================
// このフォームを前面に表示
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
end;
//=============================================================================
// このフォームを閉じる時はPDF文書も閉じてAcrobatを終了させる
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Button3Click(nil);
end;
//=============================================================================
// ファイル選択ダイアログを表示してPDF文書を選択
//
// ここで設定している位置サイズやメニューの表示は,Acrobatの次回起動時にも
// この設定が使用されるので,本来は元に戻しておくべき
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
PageCount : Integer;
Flag : OleVariant;
begin
with OpenDialog1 do begin
InitialDir := ExtractFileDir(ParamStr(0));
DefaultExt := 'PDF';
Filter := 'PDF|*.PDF';
Options := [ofReadOnly];
end;
if OpenDialog1.Execute then begin
Update;
AFile := OpenDialog1.FileName;
if not Assigned(AAcroApp) then begin
AAcroApp := TAcroApp.Create(Self);
AAcroAVDoc := TAcroAVDoc.Create(Self);
AAcroPDDoc := TAcroPDDoc.Create(Self);
end;
//開いているのは閉じる
AAcroAVDoc.Close(-1);
AAcroAVDoc.Open(AFile, '');
//AcroAVDoc1をTAcroAppのAVDocオブジェクトとする
AAcroAVDoc.ConnectTo(AAcroApp.GetAVDoc(0) as CAcroAVDoc);
//開いたドキュメントからPDDocオブジェクトを取得
AAcroPDDoc.ConnectTo(AAcroAVDoc.GetPDDoc as CAcroPDDoc);
//総頁数を取得して表示
PageCount := AAcroPDDoc.GetNumPages;
Panel1.Caption := '頁数 ' + IntToStr(PageCount);
AAcroAVDoc.SetTitle('Acrobat テスト Presented by Mr.XRAY');
//SetViewModeの5は本文のみの表示
AAcroAVDoc.SetViewMode(5);
//メニューバー,ツールバー,左側のツールバーも非表示にしてしまう
Flag := 0;
AAcroApp.SetPreferenceEx(avpShowMenuBar, Flag);
AAcroApp.SetPreferenceEx(avpShowToolBar, Flag);
AAcroApp.SetPreferenceEx(avpShowLeftToolBar, Flag);
//ウィンドウの列挙
//Acrobatのハンドルが取得できればAcroHandleにその値を返す
//そのハンドルを使用してPDF文書の表示位置とサイズを変更
EnumWindows(@EnumWindowsProc, LPARAM(@AcroHandle));
if AcroHandle <> 0 then begin
SetWindowPos(AcroHandle, 0, 0, 0, 800, 600, SWP_NOZORDER);
end;
//表示
AAcroApp.Show;
end;
end;
//=============================================================================
// ツールバー表示のトグル動作
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
Flag : OleVariant;
SetV : OleVariant;
begin
if Assigned(AAcroApp) then begin
Flag := AAcroApp.GetPreferenceEx(avpShowToolBar);
if Flag = 'false' then begin
SetV := 1;
end else begin
SetV := 0;
end;
AAcroApp.SetPreferenceEx(avpShowToolBar, SetV);
end;
end;
//=============================================================================
// PDF文書を閉じてAcrobatも閉じる
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
begin
if Assigned(AAcroApp) then begin
//下の2行はCloseAllDocsがあれば本来は不要
AAcroAVDoc.Close(1);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
//Acrobatの終了.必ずHideメソッドと対で使用する
AAcroApp.Hide;
AAcroApp.Exit;
FreeAndNil(AAcroApp);
FreeAndNil(AAcroAVDoc);
FreeAndNil(AAcroPDDoc);
end;
end;
end.
Acrobat の JavaScript API を使用して,各種のファイル形式に変換するサンプルです.
TIFF と JPEG 画像への変換状態はいいようですが,ワードや HTML ファイルへの変換では,画像と文字列の位置も文字列 (テキスト) もかなり崩れてしまいます.この結果は,Adobe Acrobat から [ファイル] [書き出し] で保存しても同じです.
PDF 文書からテキストのみを取り出すサンプルは,[434_ワードやエクセルのテキスト抽出] も参考にしてください.
JSObject を使用したプログラムは,参考リンクの記事にあるように,Acrobat JavaScript の説明書を見ながらの作業と動作確認となります.このファイル形式の変換以外にも多くの機能があります.
JSObject は,Acrobat_TLB.pas 内に定義はありません.OleVariant 型で扱います.
|
|
図17
設計時画面
- TAcroApp オブジェクト類は実行時生成
- [Button1] PDF 文書を開く
- [Button2] ワード文書として保存
- [Button3] テキスト文書で保存
- [Button4] HTML 文書として保存
- [Button5] TIFF 画像で保存
- [Button6] JPEG 画像で保存
|
|
図18
ワード文書に変換
|
|
図19
テキスト文書に変換
|
|
図20
HTML 文書に変換
- 作成されるファイルは 1 つだが各頁へのリンクとなっている
- 画像は images というフォルダが自動的に作成されてそこに格納される
- 各ページの内容は崩れている
|
|
図21
TIFF 画像に変換
- Windows フォトビューアーで表示中
- 各頁ごとにファイルができる
- TIFF と JPEG 画像への変換はかなり良い
|
|
図22
JPEG 画像に変換
- Windows フォトビューワで表示中
- 各ページごとにファイルができる
|
リスト4
PDF 文書を他の形式のファイルに変換して保存 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Acrobat_TLB, OleServer;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
btnClose: TButton;
Panel1: TPanel;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private 宣言 }
AAcroApp: TAcroApp;
AAcroAVDoc: TAcroAVDoc;
AAcroPDDoc: TAcroPDDoc;
AAcroJSObj : OleVariant;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// このフォームを閉じる時はPDF文書も閉じてAcrobatを終了させる
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
btnCloseClick(nil);
end;
//=============================================================================
// ファイル選択ダイアログを表示してPDF文書を選択
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
PageCount : Integer;
begin
with OpenDialog1 do begin
InitialDir := ExtractFileDir(ParamStr(0));
DefaultExt := 'PDF';
Filter := 'PDF|*.PDF';
Options := [ofReadOnly];
end;
if OpenDialog1.Execute then begin
Update;
AFile := OpenDialog1.FileName;
if not Assigned(AAcroApp) then begin
AAcroApp := TAcroApp.Create(Self);
AAcroAVDoc := TAcroAVDoc.Create(Self);
AAcroPDDoc := TAcroPDDoc.Create(Self);
end;
//Panel1上にPDF文書を表示
//開いているのは閉じる
AAcroAVDoc.Close(-1);
AAcroAVDoc.Open(AFile, '');
//AcroAVDoc1をTAcroAppのAVDocオブジェクトとする
AAcroAVDoc.ConnectTo(AAcroApp.GetAVDoc(0) as CAcroAVDoc);
//開いたドキュメントからPDDocオブジェクトを取得
AAcroPDDoc.ConnectTo(AAcroAVDoc.GetPDDoc as CAcroPDDoc);
//総頁数を取得して表示
PageCount := AAcroPDDoc.GetNumPages;
Panel1.Caption := '頁数 ' + IntToStr(PageCount);
//JavaScriptオブジェクトを取得
AAcroJSObj := AAcroPDDoc.GetJSObject;
end;
end;
//=============================================================================
// PDF文書をワード文書として保存
// 必ずしも成功するとは限らない.成功しても文字や画像が正しく反映されるとは限
// らない
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
SaveFileName : String;
begin
if not Assigned(AAcroApp) then exit;
if AAcroPDDoc.GetNumPages <= 0 then exit;
Screen.Cursor := crHourGlass;
try
SaveFileName := ExtractFilePath(ParamStr(0)) + 'Test.doc';
AAcroJSObj.SaveAs(SaveFileName , 'com.adobe.acrobat.doc');
except
end;
Screen.Cursor := crDefault;
end;
//=============================================================================
// PDF文書をテキストファイルとして保存
// テキストがない場合は..(要確認)
// 画像があるPDFはテキストのみの保存となる
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
SaveFileName : String;
begin
if not Assigned(AAcroApp) then exit;
if AAcroPDDoc.GetNumPages <= 0 then exit;
Screen.Cursor := crHourGlass;
try
SaveFileName := ExtractFilePath(ParamStr(0)) + 'Test.txt';
AAcroJSObj.SaveAs(SaveFileName , 'com.adobe.acrobat.plain-text');
except
end;
Screen.Cursor := crDefault;
end;
//=============================================================================
// PDF文書をHTML 4.01形式のHTMLファイルとして保存
// HTMLファイルはPDFが何頁あっても1つだけ生成される
// 画像はimagesというフォルダが自動的に作成されてその中に保存される
// PDF文書によっては失敗して例外でストップする場合あり(tryでは捕捉不可)
//=============================================================================
procedure TForm1.Button4Click(Sender: TObject);
var
SaveFileName : String;
begin
if not Assigned(AAcroApp) then exit;
if AAcroPDDoc.GetNumPages <= 0 then exit;
Screen.Cursor := crHourGlass;
try
SaveFileName := ExtractFilePath(ParamStr(0)) + 'Test401.html';
AAcroJSObj.SaveAs(SaveFileName , 'com.adobe.acrobat.html-4-01-css-1-00');
except
end;
Screen.Cursor := crDefault;
end;
//=============================================================================
// PDF文書をTIFF画像ファイルとして保存
// 複数頁のPDFは1頁に付き1つのTIFF画像ファイルとなる
//=============================================================================
procedure TForm1.Button5Click(Sender: TObject);
var
SaveFileName : String;
begin
if not Assigned(AAcroApp) then exit;
if AAcroPDDoc.GetNumPages <= 0 then exit;
Screen.Cursor := crHourGlass;
try
SaveFileName := ExtractFilePath(ParamStr(0)) + 'TIFFImages\Test.tif';
ForceDirectories(ExtractFileDir(SaveFileName));
AAcroJSObj.SaveAs(SaveFileName, 'com.adobe.acrobat.tiff');
except
end;
Screen.Cursor := crDefault;
end;
//=============================================================================
// PDF文書をJPEG画像ファイルとして保存
// 複数頁のPDFは1頁に付き1つのJPEG画像ファイルとなる
//=============================================================================
procedure TForm1.Button6Click(Sender: TObject);
var
SaveFileName : String;
begin
if not Assigned(AAcroApp) then exit;
if AAcroPDDoc.GetNumPages <= 0 then exit;
Screen.Cursor := crHourGlass;
try
SaveFileName := ExtractFilePath(ParamStr(0)) + 'JPEGImages\Test.jpg';
ForceDirectories(ExtractFileDir(SaveFileName));
AAcroJSObj.SaveAs(SaveFileName, 'com.adobe.acrobat.jpeg');
except
end;
Screen.Cursor := crDefault;
end;
//=============================================================================
// PDF文書を閉じてAcrobatも閉じる
//=============================================================================
procedure TForm1.btnCloseClick(Sender: TObject);
begin
if Assigned(AAcroApp) then begin
//下の2行はCloseAllDocsがあれば本来は不要
AAcroAVDoc.Close(1);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
//Acrobatの終了.必ずHideメソッドと対で使用する
AAcroApp.Hide;
AAcroApp.Exit;
FreeAndNil(AAcroApp);
FreeAndNil(AAcroAVDoc);
FreeAndNil(AAcroPDDoc);
end;
end;
end.
06_CreateOleObject と CreateComObject |
ワードやエクセルと同じように Acrobat の OLE オブジェクトを,CreateOleObject で生成することもできます.以下のコードはその例です.Acrobat_TLB.pas 内をみると分かりますが,これらのコードは全て同じ動作をします.
これらの方法は,オブジェクト間に ConnectTo を使わず,キャストだけでいいので,ある意味では使いやすいかも知れません. |
リスト5
Acrobat 関係オブジェクトを CreateOleObject で生成する例 - CAcroApp にキャスト |
//=============================================================================
// Acrobarを起動してPDF文書を表示
//
// App,AcroAVDoc,AcroPDDoc等はAcrobat_TLBで定義されているので使用しない
// usesにAcrobat_TLBが必要
// CreateComObjectにはusesにComObjが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
begin
AFile := ExtractFilePath(ParamStr(0)) + 'Test Acro.pdf';
AAcroApp := CreateOleObject('AcroExch.App') as CAcroApp;
AAcroAVDoc := CreateOleObject('AcroExch.AVDOC') as CAcroAVDoc;
AAcroPDDoc := CreateOleObject('AcroExch.PDDOC') as CAcroPDDoc;
//PDF文書を開く
AAcroAVDoc.Open(AFile, '');
//AcroPDDocオブジェクトを取得してPDFの頁数を表示
AAcroPDDoc := AAcroAVDoc.GetPDDoc as CAcroPDDoc;
Label1.Caption := IntToStr(AAcroPDDoc.GetNumPages);
//Showメソッドを実行しないと表示されない
AAcroApp.Show;
end;
//=============================================================================
// PDF文書を閉じてAcrobatを終了
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
AAcroAVDoc.Close(0);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
AAcroAVDoc := nil;
AAcroPDDoc := nil;
AAcroApp.Hide;
AAcroApp.Exit;
AAcroApp := nil;
end;
リスト6
Acrobat 関係オブジェクトを CreateOleObject で生成する例 - AcroApp にキャスト |
//=============================================================================
// Acrobarを起動してPDF文書を表示
//
// App,AcroAVDoc,AcroPDDoc等はAcrobat_TLBで定義されているので使用しない
// usesにAcrobat_TLBが必要
// CreateComObjectにはusesにComObjが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
begin
AFile := ExtractFilePath(ParamStr(0)) + 'Test Acro.pdf';
AAcroApp := CreateOleObject('AcroExch.App') as AcroApp;
AAcroAVDoc := CreateOleObject('AcroExch.AVDOC') as AcroAVDoc;
AAcroPDDoc := CreateOleObject('AcroExch.PDDOC') as AcroPDDoc;
//PDF文書を開く
AAcroAVDoc.Open(AFile, '');
//AcroPDDocオブジェクトを取得してPDFの頁数を表示
AAcroPDDoc := AAcroAVDoc.GetPDDoc as AcroPDDoc;
Label1.Caption := IntToStr(AAcroPDDoc.GetNumPages);
//Showメソッドを実行しないと表示されない
AAcroApp.Show;
end;
//=============================================================================
// PDF文書を閉じてAcrobatを終了
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
AAcroAVDoc.Close(1);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
AAcroAVDoc := nil;
AAcroPDDoc := nil;
AAcroApp.Hide;
AAcroApp.Exit;
AAcroApp := nil;
end;
リスト7
Acrobat 関係オブジェクトを CreateComObject で生成する例 |
//=============================================================================
// Acrobarを起動してPDF文書を表示
//
// App,AcroAVDoc,AcroPDDoc等はAcrobat_TLBで定義されているので使用しない
// usesにAcrobat_TLBが必要
// CreateComObjectにはusesにComObjが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
begin
AFile := ExtractFilePath(ParamStr(0)) + 'Test Acro.pdf';
AAcroApp := CreateComObject(CLASS_AcroApp) as AcroApp;
AAcroAVDoc := CreateComObject(CLASS_AcroAVDoc) as AcroAVDoc;
AAcroPDDoc := CreateComObject(CLASS_AcroPDDoc) as AcroPDDoc;
//PDF文書を開く
AAcroAVDoc.Open(AFile, '');
//AcroPDDocオブジェクトを取得してPDFの頁数を表示
AAcroPDDoc := AAcroAVDoc.GetPDDoc as AcroPDDoc;
Label1.Caption := IntToStr(AAcroPDDoc.GetNumPages);
//Showメソッドを実行しないと表示されない
AAcroApp.Show;
end;
//=============================================================================
// PDF文書を閉じてAcrobatを終了
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
AAcroAVDoc.Close(1);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
AAcroAVDoc := nil;
AAcroPDDoc := nil;
AAcroApp.Hide;
AAcroApp.Exit;
AAcroApp := nil;
end;
リスト8
Acrobat 関係オブジェクトを OleVariant 型で扱う場合 |
//=============================================================================
// Acrobarを起動してPDF文書を表示
// 各オブジェクトをOleVariantで扱う場合の例
//
// App,AcroAVDoc,AcroPDDoc等はAcrobat_TLBで定義されているので使用しない
// usesにAcrobat_TLBが必要
// CreateComObjectにはusesにComObjが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
AFile : String;
begin
AFile := ExtractFilePath(ParamStr(0)) + 'Test Acro.pdf';
//OleVariantで使用する場合はキャストは不要だがコード補完機能は使用不可
AAcroApp := CreateOleObject('AcroExch.App');
AAcroAVDoc := CreateOleObject('AcroExch.AVDOC');
AAcroPDDoc := CreateOleObject('AcroExch.PDDOC');
//PDF文書を開く
AAcroAVDoc.Open(AFile, '');
//AcroPDDocオブジェクトを取得してPDFの頁数を表示
//OleVariantではキャスト不要
AAcroPDDoc := AAcroAVDoc.GetPDDoc;
Label1.Caption := IntToStr(AAcroPDDoc.GetNumPages);
//Showメソッドを実行しないと表示されない
AAcroApp.Show;
end;
//=============================================================================
// PDF文書を閉じてAcrobatを終了
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
AAcroAVDoc.Close(1);
AAcroPDDoc.Close;
AAcroApp.CloseAllDocs;
//OleVariantで使用する場合はUnassigned
AAcroAVDoc := Unassigned;
AAcroPDDoc := Unassigned;
AAcroApp.Hide;
AAcroApp.Exit;
AAcroApp := Unassigned;
end;
|