Webbrowserで途中で停止したときの解除方法は

解決


武田  2013-06-09 05:46:20  No: 44645

皆様よろしくお願いします。環境はWindows7 Delphi 6 Personalです。
質問(やろうとしていること)タブブラウザを作成しています。
非常にごくまれに、サイトを読み込もうとして途中で止まってしまって、ロックします。Xボタンしか効かず再起動することになります。(決まったURLは有りません)
このロックを再起動しないで解除あるいは回避できれば、助かるのですが、具体的なコードが解りません。
教えて頂けないでしょうか。

サイトを探したのですが、原因がわからないので有効な情報も得られませんでした。
ただOnDownloadBegin、onDocumentCompleteの項目に下記のようなことが書いてあるので
すがこのような処理をすればダウンロードが途中でエラーになっても、停止できる
と書いてあるのではと想像するわけです。
http://docwiki.embarcadero.com/Libraries/XE2/ja/SHDocVw.TWebBrowser.OnDownloadComplete
説明文「OnDownloadComplete イベントハンドラを記述すると,Web ブラウザがダウンロード処理を停止した後に特定のアクションを実行できます。たとえば OnDownloadComplete イベントを使用すると,OnDownloadBegin イベントハンドラ内で開始されたダウンロード指示を停止できます。」
もしかして私が探している処理なのかなと思うのですが高度すぎで意味がわかりません。
具体的にどのようなコードを書けばよいのでしょうか。
よろしくお願いします。

type
  TIETabSheet = class(TTabSheet)
  private
    procedure WebBrowser1TitleChange(Sender: TObject;const Text: WideString);
    procedure WebBrowser1DownloadBegin(Sender: TObject);
    procedure WebBrowser1DownloadComplete(Sender: TObject);
  public
    WebBrowser1 : TWebBrowser;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TForm1 = class(TForm)
    BtnNavigate: TButton;
    EditURL: TComboBox;
    PageControl1: TPageControl;
    Panel1: TPanel;
    procedure BtnNavigateClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
・・・・・
{ TIETabSheet }
procedure TIETabSheet.WebBrowser1TitleChange(Sender: TObject;const Text: WideString);
begin
    Caption:= Text;
end;

procedure TIETabSheet.WebBrowser1DownloadBegin(Sender: TObject);
begin
    //ダウンロードを停止できる??
end;

procedure TIETabSheet.WebBrowser1DownloadComplete(Sender: TObject);
begin
    //途中でエラーが起きたら??
end;

constructor TIETabSheet.Create(AOwner: TComponent);
begin
    inherited;
    WebBrowser1                     := TWebBrowser.Create(self);
    TOleControl(WebBrowser1).Parent := Self;
    WebBrowser1.Align               := alClient;
    WebBrowser1.OnTitleChange       := WebBrowser1TitleChange;
    WebBrowser1.OnDownloadBegin     := WebBrowser1DownloadBegin;
    WebBrowser1.OnDownloadComplete  := WebBrowser1DownloadComplete;
end;

destructor TIETabSheet.Destroy;
begin
    WebBrowser1.Free;
    inherited;
end;
{ TForm1 }
procedure TForm1.BtnNavigateClick(Sender: TObject);
var
    IETab:TIETabSheet;
begin
    IETab                   :=  TIETabSheet.Create(PageControl1);
    IETab.Parent            := PageControl1;
    IETab.PageControl       := PageControl1;
    PageControl1.ActivePage := TTabSheet(IETab);

    IETab.WebBrowser1.Navigate(EditURL.Text);
end;


  2013-06-09 06:43:07  No: 44646

私も自分専用のタブブラウザを作り、IEから乗り換えてしばらく使って
いますが、特にご指摘のような動作はありませんでした。

Delphi 6 Personal + Win 7 Pro 64bit

Xボタンしか利かないという点を見ると、単にファイルのダウンロード
を強制終了すれば済むという問題ではない気がします。

もし可能であれば、怪しいイベントにログ出力のコマンドを入れるなどして、
どこのイベントで止まったか、詳細に調査をしてみるとよいのではないで
しょうか。(なんとなくですが、アドインなどが悪さをしている、という気が
します。)

もしどこかのURLで必ず起こる、という話なのであれば原因究明はかなり
早くなると思うのですが。そういうところはなんとか見つけることはでき
ませんか?


Harry  2013-06-09 08:27:22  No: 44647

>ダウンロード指示を停止できます。
これは武田さんにとって罪な説明だと思います。

この部分を現在のXE4の英語版オンラインヘルプで見ますと…
http://docwiki.embarcadero.com/Libraries/XE4/en/SHDocVw.TWebBrowser.OnDownloadComplete

>to stop an download indication
正しい訳は「ダウンロードの表示を停止できます。」ではないかと。

indication: 指示(すること)、しるし、兆候 、(計器の)表示(度数)、示度 

「ダウンロードの表示」とは?
これはOnDownloadBeginの方にある、こちらの記述と対になっていると思います。
つまりアニメーションコントロールとか、プログレスバーのこと。
http://docwiki.embarcadero.com/Libraries/XE4/ja/SHDocVw.TWebBrowser.OnDownloadBegin
http://docwiki.embarcadero.com/Libraries/XE4/en/SHDocVw.TWebBrowser.OnDownloadBegin

>For example, use the OnDownloadBegin event to launch an animation control the represents downloading or
> a progress bar that is updated by an OnProgressChange event handler.
>The control can then be stopped in an OnDownloadComplete event handler.
「例として、ダウンロード中を示すアニメーションコントロールまたはOnProgressChangeイベントハンドラによって
更新されるプログレスバーを起動するためにOnDownloadBeginイベントを使用します。
その後、それらのコントロールはOnDownloadCompleteイベントハンドラで停止できます。」

MSDNもEmbarcaderoも日本語訳を鵜呑みにせず、疑って原文を参照するのがコツだと思います。
大変きれいな日本語文なので油断してたら、本当は全然違うことが書いてあった…なんてことも。

こういった難しい問題をどう解決するかがIEコンポ使用ブラウザのキモで、門外不出事項なのかなーと。
必ず発生させる方法があれば、皆で検証できるんですがねぇ。HTTPモニタ見たりして。


武田  2013-06-09 09:13:43  No: 44648

Harryさんありがとうございます。
http://docwiki.embarcadero.com/Libraries/XE2/ja/SHDocVw.TWebBrowser.OnDownloadBegin
に書いてあるようなことですね。
ざんねん。
そう簡単ではないと考えています。
http://www.freeml.com/ap-dev/858
こういうサイトを見つけましたが、書いてある内容が解りません。
if @… = nil then real.OnDownloadBegin 
理解できるサイトをまた探してみます。
ありがとうございました。


  2013-06-10 06:49:41  No: 44649

一応念のため。
解決としては、まずどこでどのようなエラーが起こっているのかを特定する
のが先だと思います。エラーと無関係のイベントをいじったところで、
それは解決につながるかどうかは運しだいですし、むしろ解決にはまったく
つながらない、あるいは新しいバグを生み出す可能性もあります。
難しいのかもしれませんが、イベントうんぬんより、まずエラーの場所の
特定を先に行った方がよいのではないでしょうか。あなたが再現できない
エラーを、「エラーが起こります。原因は分かりません。どのようにすれば
よいか教えてください。」と言っても、質問者自身が分からないエラーの
修正方法は、他の人は特定できないのではないかと思います。


  2013-06-10 07:07:06  No: 44650

後、単純にダウンロードを強制終了したいのであれば、Stopで十分だと
思いますし、アプリケーションに何らかのエラーが生じているのであれば、
TapplicationEventsのOnExceptionでとらえることもできるでしょう。

もっとも、×ボタンしか利かないというところを見ると、アプリケーション
の制御がある部位で止まったままになってしまっているような状況でしょう
から、命令を特定のイベントに書いたところで実行されるかどうかは怪しい
ところですが。


武田  2013-06-10 21:01:57  No: 44651

あさん、ありがとうございます。
基本的には前記のコードですが、実際にはイベントは下記のイベントを使っています。
 WebBrowser1NavigateComplete2
 WebBrowser1CommandStateChange
 WebBrowser1NewWindow2
 WebBrowser1TitleChange
 WebBrowser1BeforeNavigate2
すこし変わっているとすれば、閉じるボタンがあったら無効にする、
タブ削除で閉じるようにするため。
procedure TTabSheetEx.WebBrowser1DocumentComplete(Sender: TObject;const pDisp: IDispatch; var URL: OleVariant);
var
    window : IHTMLWindow2 ;
    document :IHTMLDocument2;
    web : IWebBrowser      ;
begin//**Closeメソッドの無効化
    try
        web:= pDisp as Iwebbrowser;
        document := web.document  as IHTMLDocument2;
        window := IHTMLWindow2(Document.parentWindow);
        window.execScript('function close() {}','JavaScript' ) ;
    except end ;
end;

 IETab.WebBrowser1.Navigate(EditURL.Text,vFlag);

ナビゲートの後はイベントコードまかせで特別な処理はしていないつもりですが。
ただ実際にはNavigateはマルチスレッドで処理しています。(これは悪影響しませんか)

ApplicationEvents1: TApplicationEvents;
>OnExceptionでとらえることもできるでしょう
は、実際にはどのように書けばいいのでしょうか。やってみたいのですが。
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  case Msg.message of

  end;
end;

できましたらお手数ですが、よろしくお願いします。


武田  2013-06-10 21:20:39  No: 44652

自己レスです。追記。
途中でダウンロードが停止したURLの記録を
したような気がして探しましたら
http://www.atmarkit.co.jp/flinux/rensai/watch2010/watch03b.html
で発生したことがあります。
あまり見ない、「マウスオーバー」「Close」が有りますが
関係していませんか?
ご報告まで。


  2013-06-11 06:38:09  No: 44653

TApplicationEvents.OnExceptionを使って、アプリケーションで発生した
エラーをこのような形で表示させることができます。(試しに、任意の
プロシージャでゼロ除算などをやってみると、イメージはつかめると
思います。)

procedure TMBMain.ApplicationEvents1Exception(Sender: TObject;
  E: Exception);
begin
  MessageDlg(E.Message, mtError, [mbOK], 0); 
end;

TWebBrowserを使ったタブブラウザの作成時、想定外のところでエラー
が起こったりしたので、このイベントを使って、エラーをログに出力
させるなどしてバグ取りを行っていました。
(最近は1つもエラーが出なくなりましたが、今後もバグが出る可能性
は捨てきれないので、上記メッセージダイアログだけ出すようにして
います。)

どの程度利用価値があるかはわかりませんが、ご検討の一助としていただけ
ればと思います。

後、提示されたURLを、単純な構成で作成したブラウザと自前のタブ
ブラウザと、両方で15分程度いじってみましたが、ご指摘のような
エラーは発生しませんでした。リンクをクリックしたり、画面上部に
あるフラッシュを何度もクリックするなどしてみましたが、やはりそれ
でもエラーは発生しません。再現せず、検証が困難な状況です。


武田  2013-06-11 20:40:10  No: 44654

あさん、ありがとうございます。
小生の場合でも、1日5時間程度ネットサーフィンをして
1週間に1〜2回程度の発生なので、いままで放置してきました。
今後このエラーログを埋め込んで原因を追求してみます。
引き続きテストは行いますが、
一応この質問は終わりとさせて頂きます。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加