Webページの表示完了を知りたい

解決


Kenny  2010-10-02 05:19:16  No: 39271

D7にて、TWebBrowserを使って簡単なWebブラウザを作っています。
Webページを読み込んで表示を完了したときにある処理をしたいのですが、どのようにしてそのタイミングを取ればよいのか分かりません。
新規のページを読み込んだときにはOnCommandStateChange イベントが発生し、表示完了後にCSC_UPDATECOMMANDSが来るのでそれを利用しているのですが、Refreshメソッドで更新したときには表示完了後にOnCommandStateChange イベントが発生しないようです。
目的としては一つのWebページを表示し、定期的に表示更新し、ページを保存したいのです。


Quest  2010-10-02 06:30:08  No: 39272

OnDocumentCompleteイベントはどうですか?
ただ、こちらバージョンはDelphi2007ですが。


Kenny  2010-10-02 20:07:34  No: 39273

Questさん、ありがとうございます。
OnDocumentCompleteイベントも試してみたのですが、新規ページの読み込み表示が完了したときには
イベントが起こりますが、Refreshでは起きないようです。
一度別のページに移動してすぐに戻ると、表示完了後OnDocumentCompleteイベントが起きますから、
Refreshしても更新すべき内容がない時にはイベントが起きない、と言うことなのかも知れません。
ステータスバーに「ページが表示されました」と表示されるタイミングを知りたいだけなんですけど…。
愚直にOnStatusTextChange で  if Text='ページが表示されました' then 〜とやると取るには取れますが
不具合もありますし、あまりにもお馬鹿な気がして(^-^;


  2010-10-03 03:27:34  No: 39274

試してないが、busyプロパティは?

while IE.busy do begin
  application.processmessages;
end;
showmessage('');


Kenny  2010-10-03 09:12:58  No: 39275

あ さん、ありがとうございます。試しにこんな風にしてみました。

procedure TForm1.WebBrowser1CommandStateChange(Sender: TObject;
  Command: Integer; Enable: WordBool);
begin
  if WebBrowser1.busy=false then
    MessageBeep(MB_ICONASTERISK)
  else
    MessageBeep(MB_ICONEXCLAMATION);
end;

ステートが変わると音で分かるのですが、サイトによって上手く機能したりしなかったりしますね。
キャッシュとか、CGIの実行待ちとか、色々あるのかも知れません。

今はとりあえずチェックしたいときだけタイマーを回して、1秒ごとにReadyState=READYSTATE_COMPLETEを
チェックするようにしていますが。


  2010-10-05 06:33:15  No: 39276

>OnDocumentCompleteイベントも試してみたのですが、新規ページの読み込み表示が完了したときには
>イベントが起こりますが、Refreshでは起きないようです。

これは本当ですか?当方では起こってるように見えますが。

procedure TForm1.Button2Click(Sender: TObject);
begin
  WebBrowser1.Refresh;
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
  ShowMessage('');
end;


Kenny  2010-10-05 07:32:00  No: 39277

あ さん、ありがとうございます。
先にも書きましたが、サイトの内容によって振る舞いが違うようで、例えばgoogleであれば望んだ動作になります。
上手く動作しないサイトのURLを出せればいいのですが、仕事の関係するあまり公開していないURLですので、
同じように上手く動作しない、公開されているサイトを探して報告しますので、しばらくお待ち頂ければ感謝です。


monaa  2010-10-05 18:41:27  No: 39278

書きたくてウズウズしてたので書き込みます。

そもそも、目的の動作がNavigateなんだから、
ボタンはRefreshって書いても、同じページをNavigateしちゃえばいいだけじゃないですかね?
Refreshは仕様上DownloadCompleteしか発生しないものですから。
旧式のブラウザならともかく、今時のブラウザはNavigateでも更新されますよ。


monaa  2010-10-05 18:49:27  No: 39279

全然だめでした。
書き込む前にテストするんだった…


Kenny  2010-10-07 21:27:41  No: 39280

monaaさん、いつぞやは大変お世話になりました。

Refreshの代わりにNavigateというのは確かにその通りですね。頭が固まっていました。
ただどちらにしても、フレームページでは何度もDocumentCompleteが発生するので、何か考えないと
だめですね。当たり前ですが。
Webサイトの作りも無数に種類があるので、とりあえず社内用だけに使えればよいと言う方針で、一応
タイマーを使う方法で解決としておきます。
皆さんありがとうございました。


みかん、伊予柑  2010-10-08 02:03:36  No: 39281

>Refreshの代わりにNavigateというのは確かにその通りですね。頭が固まっていました。
>ただどちらにしても、フレームページでは何度もDocumentCompleteが発生するので、何か考えないと
>だめですね。当たり前ですが。

フレームを使用してるWEBページでの対策ならば、

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
  CurWB: IWebBrowser;
  TopWB: IWebBrowser;
  sName: string;
begin
  CurWB := pDisp as IWebBrowser;
  TopWB := (Sender as TWebBrowser).ControlInterface;
  sName := OleVariant(CurWB.Document).ParentWindow.Name;
  if CurWB <> TopWB then begin
    // サブフレーム読み込み(まだミカン)
    Memo1.Lines.Add(' SubFrame:'+ sName);
  end else begin
    // 全フレーム読み込み、いよ!完(イヨカン)だね
    // …ページ表示完了時の処理…
    Memo1.Lines.Add('MainFrame:'+ sName);
  end;
end;


Kenny  2010-10-09 01:57:13  No: 39282

みかん、伊予柑さん、ありがとうございます。サンプルコード、参考にさせて頂きます。
WebBrowserを使うのが初めてなので、四苦八苦しています…。


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

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






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