- PR -

WebBrowser コントロールを使用し、URL を見ずにどの frame かを識別することは可能ですか?

投稿者投稿内容
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-03-13 01:51
アンマネージドポインタからフレームを特定しようと試みましたが無駄でした。
というか、摩訶不思議なんですが、DocumentCompleted イベントの第一パラメータ
がなぜ WebBrowser なのか・・・HtmlWindow じゃないからどーしょーも無い、
と思いつつも、Navigating の TargetFrameName で判定、ちゅーても、名前が未設定
ならこれまたどーしょーもない。

たぶん、Navigating の Url をハッシュマップに登録する際、同一エントリがあるので
値をカウントする。

DocumentCompletedのUrl でハッシュマップから削除、但しカウント減算結果が0の時
のみ。

ハッシュマップのエントリ数が0の時が処理を走らせるタイミング。

うーん、indogo-x さんと同じようで別のような、良く分かりません。
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-03-13 02:56
コード:

Imports System
Imports System.Windows.Forms
Imports System.Security.Permissions


<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Form1

Private wb1 As New WebBrowser

Private map As Hashtable = New Hashtable

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

wb1.Dock = DockStyle.Fill
Me.Controls.Add(wb1)

AddHandler wb1.DocumentCompleted, AddressOf wb1_Completed
AddHandler wb1.Navigating, AddressOf wb1_Navigating

wb1.Navigate("C:\Documents and Settings\x\デスクトップ\HTML\FrameSet.html")

End Sub

Protected Sub wb1_Navigating(ByVal o As Object, ByVal e As WebBrowserNavigatingEventArgs)
Console.WriteLine("NAVI::{0}=>{1}", e.TargetFrameName, e.Url)
If map.ContainsKey(e.Url) Then
Dim iVal As Integer = DirectCast(map.Item(e.Url), Integer)
iVal = iVal + 1
map.Add(e.Url, iVal)
Else
Dim iVal As Integer = 1
map.Add(e.Url, iVal)
End If
End Sub
Protected Sub wb1_Completed(ByVal o As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)

Try

Console.WriteLine("LOAD::{0}", e.Url)
If map.ContainsKey(e.Url) Then
Dim iVal As Integer = DirectCast(map.Item(e.Url), Integer)
iVal = iVal - 1
If iVal = 0 Then
Console.WriteLine("DELE::{0}", e.Url)
map.Remove(e.Url)
Else
Console.WriteLine("REMA::{0}", e.Url)
map.Add(e.Url, iVal)
End If
End If

Console.WriteLine("MAPS::{0}", map.Count)

If map.Count < 2 Then
Dim mi As ICollection = map.Keys
For Each s As Uri In mi

Console.WriteLine("これ::{0}=>{1}", s, map.Item(s))
Next
End If

Catch ex As Exception
Console.WriteLine(ex.Message)

End Try

End Sub
End Class




こんな感じで、やってみたら、www.google.com/ が http://www.google.co.jp/ に変換
されて、辻褄が合わなくなってしまった。

上の実行結果がコレ、HTML は以前掲載したもの。

コード:

NAVI::=>file:///C:/Documents and Settings/x/デスクトップ/HTML/FrameSet.html
NAVI::=>http://www.google.com/
NAVI::=>http://www.yahoo.co.jp/
NAVI::=>http://www.goo.ne.jp/
NAVI::=>http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=mkktext_1&site=gootop&ord=1?
NAVI::=>http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_1&site=gootop&ord=1?
NAVI::=>http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_4&site=gootop&ord=1?
NAVI::=>http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_2&site=gootop&ord=1?
LOAD::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=mkktext_1&site=gootop&ord=1?
DELE::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=mkktext_1&site=gootop&ord=1?
MAPS::7
LOAD::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_1&site=gootop&ord=1?
DELE::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_1&site=gootop&ord=1?
MAPS::6
LOAD::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_4&site=gootop&ord=1?
DELE::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_4&site=gootop&ord=1?
MAPS::5
LOAD::http://www.google.co.jp/
MAPS::5
LOAD::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_2&site=gootop&ord=1?
DELE::http://ad.goo.ne.jp/html.ng/cat=gootop&contents=gootop_goo&kind=text_2&site=gootop&ord=1?
MAPS::4
LOAD::http://www.yahoo.co.jp/
DELE::http://www.yahoo.co.jp/
MAPS::3
LOAD::http://www.goo.ne.jp/
DELE::http://www.goo.ne.jp/
MAPS::2
LOAD::file:///C:/Documents and Settings/x/デスクトップ/HTML/FrameSet.html
DELE::file:///C:/Documents and Settings/x/デスクトップ/HTML/FrameSet.html
MAPS::1
これ::http://www.google.com/=>1




ってことで、NAVI と LOAD の数の比較と、辻褄合わない(リダイレクトされて
指定されたURIが変化するような形式)場合は、WebClient かなんか使って、個別
に対応するとか、しきい値でもって、URIの80%以上マッチ or 部分文字列マッチなら、
どーこーするとか。

リダイレクトと GET パラメータに別のURI指定するようなタイプが厄介ですね。



[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-03-13 02:58 ]
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-03-13 06:39
>ぴあちゃん(さん)

 やはり難しい感じがありますね。

 発想を変えないと行けない感じですね。。。。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-03-14 02:45
みなさまありがとうございます。
ふと ReadyState プロパティーを使ってみたところ、どうやらこれを使うべきのようです。
たとえば、
コード:
        private void webBrowser1_DocumentCompleted(object sender, 
            WebBrowserDocumentCompletedEventArgs e)
        {
            Console.WriteLine("webBrowser1.ReadyState = " + webBrowser1.ReadyState);
            if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
            {
                // このときに処理すればよい。
            }
        }


のようにすると、目論見どおりに動く感じです。
フレームごとのイベントでは Interactive の状態であり、すべて完了すると Complete になるようです。

私は、今まで、ReadyState プロパティーは、イベント駆動のプログラムではなく簡易的なポーリングで動かすようなプログラムのためだけに存在しているものかと思っていました。しかし、DocumentCompleted のようなイベントと組み合わせて使うためにも存在しているようです。
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-03-14 08:42
うまくいきましたか

引用:
イベント駆動のプログラムではなく簡易的なポーリングで動かすようなプログラムのためだけに存在しているものかと思っていました。



私もそう思ってました。
なんでもやってみないとわからないものですね。

スキルアップ/キャリアアップ(JOB@IT)