DocumentオブジェクトからIEのハンドルを取得するには?

解決


GOMA  2004-12-20 17:17:16  No: 87477  IP: [192.*.*.*]

環境:Windows2000(SP4)
言語:VB6.0(SP6)
IE  :5.5以上

いつもお世話になっています。

IEブラウザ操作関連のアプリケーションを作成しています。

そこで題記の件ですが、Documentオブジェクト(MSHTML.HTMLDocument)から辿って、
そのDocumentを含むIEのウィンドウハンドルを取得したいのですが、
良い方法は無いでしょうか。
(ブラウザはIE(バージョン5.5以上)である事は分かっているものとします)

Documentオブジェクトに対しclick等のイベントが発生した場合、
その親であるブラウザのウィンドウハンドルを知りたいのです。
IEは複数存在します。

parrentプロパティやTopプロパティで取得出来ないかとも思ったのですが、
やはり駄目なようです。

分かる方おりましたら、ご教授お願いします。

編集 削除
おっさん  2004-12-20 19:24:29  No: 87478  IP: [192.*.*.*]

ShellWindowsコレクションで、起動済みのInternetExplroer
オブジェクトを列挙して、そのDocumentオブジェクトを調べて、
InternetExplroerオブジェクトを特定する。
ってのもありかな?

編集 削除
IMA  2004-12-21 05:06:02  No: 87479  IP: [192.*.*.*]

>そこで題記の件ですが、Documentオブジェクト(MSHTML.HTMLDocument)から辿って、
>そのDocumentを含むIEのウィンドウハンドルを取得したいのですが、
この、Documentオブジェクトはどのようにして取得されているのでしょうか?
親?のIEが存在するのなら、そのDocumentオブジェクト取得時に同時にハンドルを
取得すればよいと思いますが・・・

そうでなければ、おっさん さん の提案に1票です。
→私はShellWindowsを使いサブクラスで複数IEの各イベントを取得しています。
→→Webbrowserコントロール貼り付け時と同じ程度のイベントは拾えます。

編集 削除
IMA  2004-12-21 07:41:00  No: 87480  IP: [192.*.*.*]

↑の訂正です。
私はShellWindowsを使いクラス化を行い複数IEの各イベントを取得しています。

また、サブクラスの例では
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/subc/
などが参考になるかも?

編集 削除
GOMA  2004-12-21 12:14:20  No: 87481  IP: [192.*.*.*]

おふたかた、返信ありがとうございます。

>おっさんさん
昨日湯船の中でおっさんさんが言われるようなShellWindowsの件を思いつき、今まで試していました。
行けそうな気配はあるんですが、目的のIEを特定する比較がどうもうまく行きません。

>IMAさん
Documentオブジェクトはクラスモジュールを用いて(対象が不特定で、数が動的に変化する為)、
存在する全てのものをWithEvent設定しています。
修正規模や影響の関係上、Documentオブジェクトの情報から、そのIEのハンドルを
取得する関数が作れたら、と思っています。

現在、
クリックイベントが発生したDocumentオブジェクトは分かるので、
フレームが使用されている場合を考慮し、
「イベント発生したDocumentを含むIEの最上位のDocument」

「存在するIEのDocument」
を比較して行こうという考えです。


'〜〜〜 IEハンドル取得処理(S)  〜〜〜

  Dim objShellWindows As ShellWindows  'ShellWindowsオブジェクト
    Dim lIeHwnd As Long           'IEウィンドウハンドル
    Dim iCnt1 As Integer          'ループカウンタ

  'ShellWindowsオブジェクトセット
    Set objShellWindows = CreateObject("Shell.Application").Windows()
    '変数初期化
    lIeHwnd = 0        

    '存在するShellWindow分繰返し(IEとファイルエクスプローラの判別の是非は今は置いておく)
    For iCnt1 = 0 To objShellWindows.Count -1
'※1(S)
        '指定Documentを含むIE直下のDocumentと存在する各IE直下のDocumentを比較
    '  (注:tgtDocはイベントが発生したDocumentオブジェクトとする)
        If objShellWindows(iCnt1).Document Is tgtDoc.parentWindow.Top.Document Then
'※1(E)
            '一致した場合hwnd取得
            lIeHwnd = objShellWindows(iCnt1).hwnd
          Exit For
        Else
        End If
    Next iCnt1

'〜〜〜 IEハンドル取得処理(E)  〜〜〜



上記の※1部分の比較判定個所なのですが、ここがうまくいきません。

(例1)上記例のようなオブジェクト比較。
  →一致せず(ウォッチ式では同じ内容のDocumentが一つみつかるのですが)

(例2)オブジェクト変数のアドレス取得関数(隠し関数なのですが試しで)によるアドレス比較。
   If ObjPtr(objShellWindows.Item(i).Document) = ObjPtr(docDoc.parentWindow.Top.Document) Then
  →一致せず


URL比較も考えましたが、出来れば複数存在するIE内に同じURLが存在する場合も対応したいのです。

何か良い手段はないでしょうか。

編集 削除
IMA  2004-12-21 13:06:47  No: 87482  IP: [192.*.*.*]

If objShellWindows(iCnt1).Document Is tgtDoc.parentWindow.Top.Document Then

 If objShellWindows(iCnt1).Document.body Is tgtDoc.parentWindow.Top.Document.body Then
ではダメですか?

仮にうまく行っても、正確な説明はできませんが・・

編集 削除
GOMA  2004-12-21 13:57:13  No: 87483  IP: [192.*.*.*]

>IMAさん
その方法で行けました!
同URLの判別も確認出来ました。
最終的にはIEの判別も含め以下のようになりました。

    '存在するShellWindow分繰返し
    For iCnt1 = 0 To objShellWindows.Count -1
    'IEとファイルエクスプローラの判別
    If UCase(TypeName(objShellWindows(iCnt1).Document)) = "HTMLDOCUMENT" Then
          '指定Documentを含むIE直下のDocumentと存在する各IE直下のDocumentを比較
      '  (注:tgtDocはイベントが発生したDocumentオブジェクトとする)
      If objShellWindows(iCnt1).Document.body Is tgtDoc.parentWindow.Top.Document.body Then
              '一致した場合hwnd取得
              lIeHwnd = objShellWindows(iCnt1).hwnd
            Exit For
          Else
          End If
        Else
        End If
    Next iCnt1

余談ですが「フレームの親はbodyエレメントないけれど問題ないかな」
等と一瞬考えてしまいました。意味合いは異なりますね。お恥ずかしい。
しかし、Documentで一致してくれてもいいような?
これもきっと理由があるのでしょうね。
追々調べて見ようと思います。
VB自体は経験6年程なのですがDOMの概念は昨年初めて知りまして、
まだ学ぶべき事は多そうですね。

おふたかた、どうもありがとうございました。

編集 削除