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

解決


GOMA  2004-12-20 17:17:16  No: 87477

環境: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

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


IMA  2004-12-21 05:06:02  No: 87479

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

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


IMA  2004-12-21 07:41:00  No: 87480

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

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


GOMA  2004-12-21 12:14:20  No: 87481

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

>おっさんさん
昨日湯船の中でおっさんさんが言われるような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

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

>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の概念は昨年初めて知りまして、
まだ学ぶべき事は多そうですね。

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


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

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







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