喫茶XRAYトップページ

[スレッド全体
]

[12106] PDFの表示終了時のエラー返信 削除
2018/8/1 (水) 06:42:11 Mr.XRAY
以下のページを参考にして,
http://mrxray.on.coocan.jp/Delphi/plSamples/720_Acrobat.htm

Delphi10.2, Acrobat Reader DC で

AcroPDF コンポーネントを入れて表示等はうまくいくが,
フォームを閉じた際に添付している画像のエラーが現れる.
Delphi2007ではうまくシステム稼動していたが,
Delohi10.2ではそのままではメなようである.

と言うことですが,残念ながら分かりません.
一般的に言えば,このようなアドレス違反は,メモリ上にデータがない
(オブジェクト等も含めて) 領域にアクセス,操作した場合に発生します.


[12107] Re:PDFの表示終了時のエラー返信 削除
2018/8/1 (水) 09:07:35 Mr.XRAY
> AcroPDF コンポーネントを入れて表示等はうまくいくが,
> フォームを閉じた際に添付している画像のエラーが現れる.


Delohi10.2 で新規にプロジェクトを作成して,単純な動作のコードを書いて
実行しながらテストするしかないかと...
トラブルが発生した時の定石なので,既にやっているとは思いますが.


[12112] Re2:PDFの表示終了時のエラー返信 削除
2018/8/2 (木) 08:45:49 mountain079
▼ Mr.XRAYさん

> Delohi10.2 で新規にプロジェクトを作成して,単純な動作のコードを書いて
> 実行しながらテストするしかないかと...
> トラブルが発生した時の定石なので,既にやっているとは思いますが.


ありがとうございました。
確かに他のコードが何かエラーを起こしているかも知れませんので、
シンプルな作り方で原因を追究していきたいと思います。

[12113] Re3:PDFの表示終了時のエラー返信 削除
2018/8/2 (木) 08:57:31 Mr.XRAY
▼ mountain079さん,こんちには.

> 確かに他のコードが何かエラーを起こしているかも知れませんので、
> シンプルな作り方で原因を追究していきたいと思います。


ですね.大変だとは思いますが.
テストのプロジェクトは「新規」に作成してください.
これはちょっと重要です.
他の掲示板などでも,特に Ansi 版の Delphi で過去に作成したプログラム
を新しいバージョンでコンパイルした時のエラーの質問があります.

実際にそれらの方に確認したわけではないのですが,新規の方が確実です.
面倒ですけどね.結局それが近道だと思います.

[参考]
[別バージョンで作成されたプロジェクトの利用]
http://mrxray.on.coocan.jp/Delphi/Others/Delphi_Versionl.htm


# メールからこちらの喫茶XRAY に来ていただきありがとうございます.
# 皆さん誘導してもなか中々こちらにはいらっしゃいません (笑)


[12118] Re4:PDFの表示終了時のエラー返信 削除
2018/8/4 (土) 10:23:42 mountain079
▼ Mr.XRAYさん
> テストのプロジェクトは「新規」に作成してください.
> これはちょっと重要です.


ご教授ありがとうございます。

全くの新規プロジェクトで作成をして、
FormCreate時に
AcroPDF1.src:=開きたいPDFファイルパス;

と書いただけでは閉じる際にもエラーが出ずに成功します。

しかし、
AcroPDF1.src:=開きたいPDFファイルパス;
AcroPDF1.setShowToolbar(True);

など、AcroPDFのsrc以外のプロパティに値をセットすると、閉じる際にアドレス違反エラーがでます。

AcroPDF1.LoadFile(開きたいPDFファイルパス);

なども同じです。。。

ということは、AcrobatDCのAcroPDF.Dllがそもそもおかしい?
ということくらいしか考えられません。

ひとまずtWebBrowserで表示させる?等の方法で逃げたいと思いますが、少し気になりますね。。。笑

[12119] Re5:PDFの表示終了時のエラー返信 削除
2018/8/4 (土) 11:55:36 Mr.XRAY
> 全くの新規プロジェクトで作成をして、
> FormCreate時に
> AcroPDF1.src:=開きたいPDFファイルパス;
>
> と書いただけでは閉じる際にもエラーが出ずに成功します。


なるほど.
AcroPDF1 にその PDF ファイルをセットすると,
PDF のオブジェクトが生成されるわけですが,
まだ PDF のオブジェクトの全て生成が完了しないためかも知れません.

PDF 文書を開くのに少し時間がかかりますよね ?
そういうことかも知れません.
セットしたプロパティの何かが残っているが,実際にそのオブジェクト
が操作できないという状態なのかも知れません.

複数のフォームを実行時に生成するときも同じような現象が発生
することがあります.(きちんと処理すれば発生しません)
アプリが終了して全てウィンドウ (フォーム) が閉じてから,
アクセス違反のダイアログが現れることがあります.
初めてそのダイアログを見たときは,他のアプリが出しているんじゃないの ?
と思ったりしました (笑)


[12120] Re6:PDFの表示終了時のエラー返信 削除
2018/8/4 (土) 12:21:27 福士
ちなみにフォームのOnCreateではなくOnShowで処理をしても同じですか?
COM/ActiveXの類いやシェルコントロールはOnCreateだとタイミング的に
早すぎて問題があった気がするので…

[12121] Re7:PDFの表示終了時のエラー返信 削除
2018/8/4 (土) 15:14:54 mountain079
▼ 福士さん
> ちなみにフォームのOnCreateではなくOnShowで処理をしても同じですか?
> COM/ActiveXの類いやシェルコントロールはOnCreateだとタイミング的に
> 早すぎて問題があった気がするので…


私の説明が間違っておりまして、正しくはFormShowでした。

新規VCLフォームアプリケーションを作成し、
1つのフォームのOnShowにソースを書いています。

OnClose等他のソースは1行も書いておらず、、、

色々と探し回った結果、Excel VBAでもsrc以外のプロパティを変更すると、異常終了するそうです。。

Adobeに振り回されてばかり笑

すくなくともAdobeReader\までは使用できていたので、とりあえずtWebBrowserでしのげればなぁと・

ただし、tWebBrowserはやはり遅いですが。。

[12122] Re8:PDFの表示終了時のエラー返信 削除
2018/8/5 (日) 01:00:23 taka
OnCloseQueryイベントでプロパティを変更して接続を断てばいいのでは?

試してないので知りませんけどね

[12123] Re9:PDFの表示終了時のエラー返信 削除
2018/8/5 (日) 11:41:31 Mr.XRAY
> OnCloseQueryイベントでプロパティを変更して接続を断てばいいのでは?

プロパティの内容にもよるかも知れませんが,確認はできそうな..

福士さんが OnShow のことを書いていたので,もしかしたら,
と思ったら OnShow イベントだったんですね (^^);

アプリはバージョン UP で機能が増え,その分他のプログラムからの操作
は面倒になってきているようです.
Excel の VBA でも同様の現象が発生するのもそういったことかも知れません.

他のアプリを操作する場合,そのアプリの操作対象のオブジェクトの生成完了を
確実に検出してから操作しないと,いろいろトラブルの元になりますね.
この生成完了を検出するのは結構難しいです.
例えば Delphi の IDE なんかは 450 以上のウィンドウを生成しますが,
その生成順序は必ずしも同じではありません.
Excel も CBT フックをしてウィンドウの生成を観察するとやはり生成順序は
常に同じではないです.

ともかく,他のアプリの操作は難しいです.ハイ.
Windows XP あたりまではそこそこ操作ができたようですが.


[12124] Re10:PDFの表示終了時のエラー返信 削除
2018/8/5 (日) 11:56:20 Mr.XRAY
> ともかく,他のアプリの操作は難しいです.ハイ.

最終的な手段はフックかも知れません.
相手が他のアプリなのでローカルフックでは補足できる可能性は低いです.

[03_位置とサイズを指定してアプリを起動 - WH_CBT フック使用]
http://mrxray.on.coocan.jp/Delphi/plSamples/266_App_CreateOpen.htm#03

グローバルフック,これもまた難しい ... (^^;


[12127] Re11:PDFの表示終了時のエラー返信 削除
2018/8/7 (火) 23:30:28 taka
▼ Mr.XRAYさん
> > ともかく,他のアプリの操作は難しいです.ハイ.
>
> 最終的な手段はフックかも知れません.
> 相手が他のアプリなのでローカルフックでは補足できる可能性は低いです.
>
> [03_位置とサイズを指定してアプリを起動 - WH_CBT フック使用]
> http://mrxray.on.coocan.jp/Delphi/plSamples/266_App_CreateOpen.htm#03
>
> グローバルフック,これもまた難しい ... (^^;


http://mrxray.on.coocan.jp/Delphi/plSamples/720_Acrobat.htm
を参考にしてインポート後 試してみました。

なにか呼び出して、AcroPDF1の接続が確立してから
アプリを終了すると終了時にアクセス違反が発生するようです。

procedure TForm1.Button1Click(Sender: TObject);
  var info : string;
begin
  info := AcroPDF1.GetVersions();
  MessageBox(Handle, PWideChar(info), '情報', 0);
end;

を実行後にアプリを終了しても アクセス違反になります

一度違反が発生したら、2回目はないようなので
終了前に手動でコンポーネントを破棄してしまえばいいのかもしれないです。
// try except でエラーを破棄する

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := True;
  if Assigned(AcroPDF1) then
  try
    FreeAndNil(AcroPDF1);
  except
    AcroPDF1 := nil;
  end;
end;

 ---------------------------------------------

デバッガで実行して、このコードで故意に落とすと
procedure TForm1.ButtonDebugClick(Sender: TObject);
begin
  if Not Assigned(AcroPDF1) then
    Exit;
  AcroPDF1.GetVersions();
  FreeAndNil(AcroPDF1); // ここにブレークポイントを設置する
  // Buttonをクリックし、停止したらトレース実行する
  // system::_IntfClear で落ちる
end;

system: _IntfClear
の IInterface._Releaseの次の行で落ちているのがわかりました。
内容は、PUREPASCALの部分のコードなんでしょうけど
アセンブラで書かれているのでわかりません。

落ちている前後を
Delphi10.2とDelphi2005と比べるとコードはほぼ同じですので、
気が向いたら Delphi2005で同じエラーが発生するか確認してみようと思います


[12128] Re12:PDFの表示終了時のエラー返信 削除
2018/8/8 (水) 06:27:53 Mr.XRAY
▼ takaさん,お手数おかけします.スミマセン.
やっと重い腰を上げました (^^;

Windows 7 U64(SP1) + Delphi XE(UP1) Pro + Adobe Reader DC
でテストしました.
テストしたのは以下のサンプルです.
IDE でコンパイルして実行.PDF 文書を表示するだけでフォームを閉じると
EXE 終了時に例外が発生しました.
PDF 文書を表示しなければ例外は発生しませんでした.

[02_PDF 文書のフォームへの表示]
http://mrxray.on.coocan.jp/Delphi/plSamples/720_Acrobat.htm#02

taka さんの OnloseQuery コードを追加して実行してみました.
例外は発生しなくなりましたが,メモリリークが発生しました.
で,Delphi XE5(UP2) Pro で同じように実行してみました.
今度は例外も発生しました.

ん ? AcroPDF1.free が操作できない ? メモリリーク ?

  TAcroPDF = class(TOleControl)
  TOleControl = class(TWinControl, IUnknown, IOleClientSite,....

となっています.ああぁ〜 ! もしかして...
で思い出しました.昔同じ様な現象を経験したことがあります.
以下のサンプルです.参照カウンタです.

[コンポーネント TplExplorerFolderView のソースコード]
http://mrxray.on.coocan.jp/Delphi/plSamples/947_ExplorerBrowser.htm#list5

てなわけで以下のようにしてみてください.

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  //TAcroPDF の参照カウンタがインクリメントされていないようなので
  //解放破棄操作される前に AddRef しておく
  AcroPDF1.ControlInterface._AddRef;
end;



[12132] Re13:PDFの表示終了時のエラー返信 削除
2018/8/8 (水) 12:07:47 Mr.XRAY
> テストしたのは以下のサンプルです.
> IDE でコンパイルして実行.PDF 文書を表示するだけでフォームを閉じると
> EXE 終了時に例外が発生しました.
> PDF 文書を表示しなければ例外は発生しませんでした.


こういう質問だったらすぐ取り掛かったんですけどね (笑)
掲載しているサンプルコードを参考にしていろいろやっているということでしたので,
その「いろいろ」な部分が問題なのかな ? と思っていましたから.

過去の経験から,
「掲載しているサンプルではそういう現象は発生しませんでした」
とレスすると,
「他にコードを追加したり変更しています..」
となってしまうことが多いので.

まっ,言い訳ですけど (^^;
taka さんのテストがなければ放置だったかも知れません.
問題点をテストしてくださった taka さんに感謝です.


[12133] Re14:PDFの表示終了時のエラー返信 削除
2018/8/8 (水) 12:23:57 taka
▼ Mr.XRAYさん
> > テストしたのは以下のサンプルです.
> > IDE でコンパイルして実行.PDF 文書を表示するだけでフォームを閉じると
> > EXE 終了時に例外が発生しました.
> > PDF 文書を表示しなければ例外は発生しませんでした.
>
> こういう質問だったらすぐ取り掛かったんですけどね (笑)
> 掲載しているサンプルコードを参考にしていろいろやっているということでしたので,
> その「いろいろ」な部分が問題なのかな ? と思っていましたから.
>
> 過去の経験から,
> 「掲載しているサンプルではそういう現象は発生しませんでした」
> とレスすると,
> 「他にコードを追加したり変更しています..」
> となってしまうことが多いので.
>
> まっ,言い訳ですけど (^^;
> taka さんのテストがなければ放置だったかも知れません.
> 問題点をテストしてくださった taka さんに感謝です.

やっぱり参照カウンタの不具合でしたか。
Delphi2005でも再現しました。

修正コードみました。
Delphiのインポートツールのバグなんですね。

[12134] Re15:PDFの表示終了時のエラー返信 削除
2018/8/8 (水) 22:58:49 Mr.XRAY
▼ takaさん,どうもです.

taka さんの

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := True;
  if Assigned(AcroPDF1) then
  try
    FreeAndNil(AcroPDF1);
  except
    AcroPDF1 := nil;
  end;
end;

のコードがなかったら気が付かなかったでしょうね.
やはりプログラムというのはコードを書いて,それが実行されるわけですから,
具体的なコードがあるというのは強力です.
コードがなければ抽象的な話になってしまいますから.

> 修正コードみました。
> Delphiのインポートツールのバグなんですね。


ある意味ではやむを得ないということもあるかも知れません.
操作対象の COM オブジェクトはパーションによって機能が変わってきますから.
で,修正コードについて書いていませんでした.AcroPDFLib_TLB.pas にある

  TAcroPDF = class(TOleControl)
  private
    FIntf: IAcroAXDocShim;
    function  GetControlInterface: IAcroAXDocShim;

の FIntf が TAcroPDF のコンテナの実体ですので,destructor を override
して以下のように強制的に nil にしました.
この nil も AcroPDF1 := nil; がヒントです (^^;

destructor TAcroPDF.Destroy;
begin
  FIntf := nil;
  inherited;
end;


[12153] Re16:PDFの表示終了時のエラー返信 削除
2018/8/16 (木) 11:25:32 mountain079
▼ Mr.XRAYさん▼ takaさん

返信遅れて申し訳ございません。


色々と試していただき、誠にありがとうございます。

今回は急ぎの対応でしたので、tWebBrowserでしのぎましたが、
原因も追究していただけたようで、今後は再度AcroPDFでの作成を行っていきたいと思います。


私も皆様のお役に立てるよう、日々勉強に励みます。

本当にお世話になりました。

[▼次のスレッド]
INCM/CMT
Cyclamen v3.82