WebBrowserイベントについて への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 tecc  (社会人) 投稿日時 2009/5/19 08:32:59
返信ありがとうございます。

>>この処理がどういう目的で記述されているのか
入門目的用にWebBrowserに任意のページを表示し
その完了を取得する。というコードを作成しようとしました。
(せっかく、お答えいただいたのに入門目的などで申し訳ないです)

While done = False
>     Application.DoEvents()
End While

>>このようなループ待機を行ってはいけません。
了解しました。予測しにくい問題が発生するのは好ましくありませんので
熟考してみます。

>>Navigate メソッドは、『オーバーロード』されていない
VS2008のヘルプのNavigateメソッドの項目に

オーバーロードされます。 WebBrowser コントロールに
指定された場所にあるドキュメントを読み込みます。

とあった為、メソッドを呼び出す事をオーバーロードというのかと思っていました。

オーバーロードとは
戻り値や引数の数やが異なる同名のメソッドや関数を複数個定義する事なのですね。

>>DocumentCompleted イベントは WebBrowser が発生させる物
了解しました。質問の根底として、Navigateを行ったクラスでDocumentの完結を
行わないといけないのかと悩んでいました。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/5/19 04:24:02
> 検討違いな事があればご指摘ください。
そもそも、この処理がどういう目的で記述されているのかわからないので、
回答に困るのですが…とりあえずは一般論の一つという事で回答しておきます。


> While done = False
>     Application.DoEvents()
> End While
このようなループ待機を行ってはいけません。

DoEvents を無闇矢鱈と呼んでしまうと、イベント処理中に次のイベント再入が発生してしまい、
予測しにくい問題を引き起こします。それに、見た目の CPU 仕様率も跳ね上がってしまいますよ。
(Ctrl+Shift+Esc を押して、タスクマネージャを表示させた状態でループを実行させてみてください)

まずはコードの見直しを行い、ループ待機を行っている部分をイベント処理に書き直す事を検討してみてください。

例えば、『チェックボックスの値が変更されたら、○○○という処理を解する』という仕様があった場合、
「CheckBox1.Checked が変化するまでループで待機する」なんてコードは書きませんよね?
通常は、CheckBox1 の CheckedChanged イベントの中に ○○○ の処理を記述するかと思います。


> 質問1:Navigateメソッドをオーバーロードした場合に
どういう意味でしょうか?
提示されたコードの Navigate メソッドは、『オーバーロード』されていないようですが…。


> DocumentCompletedをどちらのクラスで
> 発生させれば良いのでしょうか?
ここで比較しているクラスとは、「cWebBrowser クラス」と「Form1 クラス」のことでしょうか。

だとしたら、DocumentCompleted イベントは WebBrowser が発生させる物であって、
cWebBrowser や Form1 が、同名イベントを追加発生(RaiseEvent)させる物ではありません。
一般的には、DocumentCompleted イベントを受け取る(イベントに応答させる)だけでしょう。


> 質問2:質問1と関連してcWebBrowserクラスにてDocumentCompletedイベントを発生
> させるには、Inherits WebBrowserにてWebBrowserを継承するのが適切なのですか?
Inherits させた場合、継承元のクラスが自動的にイベントを発生させますので、
自分であえて呼び出す必要はありません。


どのような目的のために、イベントを独自に発生させようとしているのかわからないので
具体的な回答はできませんが、もし、イベントの発生条件を変更したいという意味であれば、
MyClass.OnDocumentCompleted と MyBase.OnDocumentCompleted とを
適切に呼び分ける必要があるでしょう。すなわち、OnDocumentCompleted メソッドを
『オーバーライド』する必要があるということです。
投稿者 (削除されました)  () 投稿日時 2009/5/19 04:22:01
(削除されました)
投稿者 tecc  (社会人) 投稿日時 2009/5/19 02:03:59
です。

基本的な事なのかもしれませんが教えてください。
社会人なのですが、VB.NETについては小学生以下です。
検討違いな事があればご指摘ください。

イベントについてです。

フォームにWebBrowserコントロールとTextBoxとButtonを設置しました。

質問1:Navigateメソッドをオーバーロードした場合にDocumentCompletedイベントを
発生させページの読み込みの完了を知りたい場合、DocumentCompletedをどちらのクラスで
発生させれば良いのでしょうか?

※私的には、cWebBrowserクラスで完結させるのが良いと思っています。

質問2:質問1と関連してcWebBrowserクラスにてDocumentCompletedイベントを発生
させるには、Inherits WebBrowserにてWebBrowserを継承するのが適切なのですか?

※もしくはイベントを作成するのが普通?Form1クラスのWebBrowserイベントが発生した時
cWebBrowserクラスの表示制御用の変数を変更するとか・・。

'フォームクラス 
Imports System.Windows.Forms
Public Class Form1
    Dim cwb As New cWebBrowser
    Private Sub Button1_Click _
(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
        
Dim stURL As String = Me.TextBox1.Text
        Try
            Call cwb.WWWNavigate(WebBrowser1, stURL)
        Catch
            MessageBox.Show(e.ToString())
        End Try
    End Sub
End Class


'cWebBrowserクラス 
Private done As Boolean = False
Public Class cWebBrowser
    Private done As Boolean = False
    Public Sub WWWNavigate(ByVal wb As WebBrowser, ByVal cinURL As String)
        wb.Navigate(cinURL)
        While done = False
            Application.DoEvents()
        End While
    End Sub
End Class