Solved

WebBrowser detection

Posted on 2002-03-10
21
704 Views
Last Modified: 2012-05-04

PROBLEM: I can't find a function to enumerate non-standalone Internet Explorer web browsers on a system. The "Microsoft Internet Controls" (shdocvw.dll) function only "sees" separate Internet Explorer applications, not web browser controls by other apps.

EXAMPLE:

  Open a VB project.  Go to Projects/References and check "Microsoft Internet Controls" (shdocvw.dll).

  Create a form with the following code:

'---------------------------------------------------
Private Sub Command1_Click()

 Dim SWs As New SHDocVw.ShellWindows
 Dim IE As SHDocVw.InternetExplorer
 For Each IE In SWs
   MsgBox "found a browser: " & IE.FullName & vbCrLf & IE.hWnd
 Next
 End Sub
'---------------------------------------------------


  If you run it without any other application running, it should return nothing.  If you open up Internet Explorer, it will detect that IE application.

  So far, no problem.

  Now, for the VB project, go to Project/Components and add "Microsoft Internet Controls" (shdocvw.dll).  Drag a webbrowser container onto the form.

  Add the following to your Form_Load:

'---------------------------------------------------
Private Sub Form_Load()
   WebBrowser1.Navigate "www.mamma.com"
End Sub
'---------------------------------------------------

 When you run the project now, you should see the web page to www.mamma.com displayed.

 PROBLEM:  But when you click the Command1 button, you still only detect the standalone IE application.  
 QUESTION:  HOW DO YOU DETECT OR ENUMERATE OTHER WEBBROWSERs THAT ARE ACTIVE ON YOUR COMPUTER?

 (Let's pretend like the other web browser isn't really part of your own project - it is really running on another application.  I used a WebBrowser control on the same detection project for brevity.)

  (Also, I need a solution that doesn't use the "ObjectFromLResult" function in the oleacc.dll which sucks big time for Win95 and Win98 boxes.)
0
Comment
Question by:EasyAim
  • 9
  • 8
  • 2
  • +2
21 Comments
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6855747
I think you could detect webbrowser control if you set registerasbrowser property.
0
 
LVL 28

Expert Comment

by:Ark
ID: 6855913
Hi
=====Bas module code===
Private Declare Function EnumChildWindows& Lib "user32" (ByVal hParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long)
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function EnumWindows& Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long)
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long

Dim sURLs() As String
Dim nCount As Integer

Public Function EnumAllBrowsers() As Variant
   EnumWindows AddressOf EnumWinProc, 0
   EnumAllBrowsers = sURLs
End Function

Function EnumWinProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
  If GetWndClass(hWnd) = "Shell DocObject View" Then
     nCount = nCount + 1
     ReDim Preserve sURLs(nCount - 1)
     sURLs(nCount - 1) = GetWndText(GetParent(hWnd))
  End If
  EnumChildWindows hWnd, AddressOf EnumChildWinProc, 0
  EnumWinProc = 1
End Function

Function EnumChildWinProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
  If GetWndClass(hWnd) = "Shell DocObject View" Then '
     nCount = nCount + 1
     ReDim Preserve sURLs(nCount - 1)
     sURLs(nCount - 1) = GetWndText(GetParent(hWnd))
  End If
  EnumChildWinProc = 1
End Function

Private Function GetWndClass(hWnd As Long) As String
  Dim k As Long, sName As String
  sName = Space$(128)
  k = GetClassName(hWnd, sName, 128)
  If k > 0 Then sName = Left$(sName, k) Else sName = "No class"
  GetWndClass = sName
End Function

Private Function GetWndText(hWnd As Long) As String
  Dim k As Long, sName As String
  sName = Space$(128)
  k = GetWindowText(hWnd, sName, 128)
  If k > 0 Then sName = Left$(sName, k) Else sName = "No name"
  GetWndText = sName
End Function

'=========Form code=======
Private Sub Command1_Click()
   Dim Result As Variant
   Result = EnumAllBrowsers
   For i = 0 To UBound(Result)
       Debug.Print Result(i)
   Next i
End Sub

Private Sub Form_Load()
  WebBrowser1.Navigate "http://www.astalavista.com"
End Sub

Cheers
0
 

Author Comment

by:EasyAim
ID: 6857242
Ark,

  I appreciate your code.  I'm embarrassed that I did not clarify my question better....

  Similar to your code, I can get the 'hWnd' of a webbrowser object; however, I can not extract any useful information from the object using only the 'hWnd'.

  What I need is to instantiate an 'SHDocVw.ShellWindows' for a specific webbrowser so I can extract the HTML code out of it similar to my original example code.

   In other words, my goal is:

  Given a webbrowser object (i.e. "Shell DocObject View" or "Internet Explorer_Server") I need to extract the HTML code out of it.

   I'll double the points for this solution.


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 28

Expert Comment

by:Ark
ID: 6859899
Hi
Did you see this sample http://www.domaindlx.com/e_morcillo/scripts/tips/en/ie/iedom.asp ?
 Though it use oleacc.dll, it works for me at w98.

Cheers
0
 

Author Comment

by:EasyAim
ID: 6863476
Ark,

  Yes, I am currently using the oleacc.dll to perform a similar method of extracting the DOM from webserver objects.
  The problem is that the oleacc.dll apparently is not backward compatible and installation packages for Win95, Win98, Win2000, etc.. are notoriously difficult to "get right" due to this sorry dll design.
 
   I can't believe the only method of extracting HTML from a webbrowser object on a computer is through the use of this magical dll.
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6864864
It is not the only way but it depends upon from what window you need to do it.
0
 

Author Comment

by:EasyAim
ID: 6866581
Any more information there, Richie?  What do you mean?  I'm primarily interested in extracting info from the "Internet Explorer_Server" component (without using the oleacc.dll).
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6869564
Well, i misread previous comments, sorry.
What i did try is a different approach:
What about to catch IE_server "creation" instead of enumerate
running instances?
Bad idea!
As i told previously, we cannot enumerate webbrowser with shellwindows if the app with webbrowser control has not setted its property
registerasbrowser to true.
Just do a try with your first code setting that property and you will see what i mean.
I am in a dead way.
0
 

Author Comment

by:EasyAim
ID: 6871044
Thanks for your research Richie.  And good try with that English language.   If I understand you correctly, you are also at a "dead end" trying to solve this problem also.

I hate threads that start out promising and then just peter out due to no solution.

I'll keep ratching up the points for a solution for a few more days.

Again, the question is:  Using Visual Basic, how do you extract the DOM or HTML code from an "Internet Explorer_Server" component without using the 'oleacc.dll'?
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6872084
To this very time, i think you have to stick to oleacc dll. Sorry.
Note: I did a try enumerating child windows (strange, it doesn't returns "Internet Explorer_Server" but:
"Shell Embedding" and
"Shell DocObject View")

PS: My english is more ugly than my code ;)
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6873305
I don't know why but i had to do a little modification to
Edammo's code in link posted by Ark.
It simply doesn't works for me!!!

Well, this code assumes that you have a command button, a listbox,
a richtextbox, a webbrowser control and a reference to Microsoft HTML Object library (to do things easily, just as your example ;)
You need a module also.
Take in mind that this code could be modified to do things more "correct", i just did a "working" one in a hurry.

'Module:
Option Explicit

'in a module
'
Public Const SMTO_ABORTIFHUNG = &H2
Public DocHwnd As Long
Public arrHwnd() As Long    'to store handles
Dim iedoc As IHTMLDocument2

Type UUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(0 To 7) As Byte
End Type
Declare Function RegisterWindowMessage Lib "user32" _
   Alias "RegisterWindowMessageA" ( _
      ByVal lpString As String) As Long

Declare Function SendMessageTimeout Lib "user32" _
   Alias "SendMessageTimeoutA" ( _
      ByVal hwnd As Long, _
      ByVal msg As Long, _
      ByVal wParam As Long, _
      lParam As Any, _
      ByVal fuFlags As Long, _
      ByVal uTimeout As Long, _
      lpdwResult As Long) As Long
     
Declare Function ObjectFromLresult Lib "oleacc" ( _
      ByVal lResult As Long, _
      riid As UUID, _
      ByVal wParam As Long, _
      ppvObject As Any) As Long
Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean

Function IEDOMFromhWnd(hwnd As Long) As IHTMLDocument
Dim IID_IHTMLDocument As UUID
Dim spDoc As IUnknown
Dim lRes As Long
Dim lMsg As Long
Dim hr As Long

' Register the message
lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT")
           
' Get the object
Call SendMessageTimeout(hwnd, lMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes)

If lRes Then
   
   ' Initialize the interface ID
   With IID_IHTMLDocument
      .Data1 = &H626FC520
      .Data2 = &HA41E
      .Data3 = &H11CF
      .Data4(0) = &HA7
      .Data4(1) = &H31
      .Data4(2) = &H0
      .Data4(3) = &HA0
      .Data4(4) = &HC9
      .Data4(5) = &H8
      .Data4(6) = &H26
      .Data4(7) = &H37
   End With
   
   ' Get the object from lRes
   hr = ObjectFromLresult(lRes, IID_IHTMLDocument, 0, IEDOMFromhWnd)
   
End If
End Function


Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
    Static idx As Integer ' to use for array
    ReDim Preserve arrHwnd(idx)
    arrHwnd(idx) = hwnd
    idx = idx + 1
    'continue enumeration
    EnumWindowsProc = True
End Function

Public Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
    Dim sSave As String, lret As Long
    sSave = Space$(255)
    lret = GetClassName(hwnd, sSave, 255)
    sSave = Left$(sSave, lret)
    If sSave = "Internet Explorer_Server" Then
        Set iedoc = IEDOMFromhWnd(hwnd)
        If Not iedoc Is Nothing Then
            With frmWB.rtb
                .Text = .Text & vbCrLf & vbCrLf & iedoc.documentElement.innerHTML & vbCrLf & vbCrLf & "|------- Begin of new HTML Document ---------|"
            End With
        End If
    'DocHwnd = hwnd
    End If
    'continue enumeration
    EnumChildProc = 1
End Function

'******************************************************************
' form:
VERSION 5.00
Object = "{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}#1.1#0"; "SHDOCVW.DLL"
Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "RICHTX32.OCX"
Begin VB.Form frmWB
   Caption         =   "Form1"
   ClientHeight    =   6510
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   6765
   LinkTopic       =   "Form1"
   ScaleHeight     =   6510
   ScaleWidth      =   6765
   StartUpPosition =   3  'Windows Default
   Begin RichTextLib.RichTextBox rtb
      Height          =   2145
      Left            =   15
      TabIndex        =   3
      Top             =   4320
      Width           =   6705
      _ExtentX        =   11827
      _ExtentY        =   3784
      _Version        =   393217
      Enabled         =   -1  'True
      ScrollBars      =   2
      TextRTF         =   $"frmWB.frx":0000
   End
   Begin VB.ListBox List1
      Height          =   3765
      Left            =   15
      TabIndex        =   2
      Top             =   525
      Width           =   2130
   End
   Begin VB.CommandButton Command1
      Caption         =   "Command1"
      Height          =   405
      Left            =   45
      TabIndex        =   1
      Top             =   60
      Width           =   2085
   End
   Begin SHDocVwCtl.WebBrowser wb1
      Height          =   4230
      Left            =   2205
      TabIndex        =   0
      Top             =   45
      Width           =   4560
      ExtentX         =   8043
      ExtentY         =   7461
      ViewMode        =   0
      Offline         =   0
      Silent          =   0
      RegisterAsBrowser=   0
      RegisterAsDropTarget=   1
      AutoArrange     =   0   'False
      NoClientEdge    =   0   'False
      AlignLeft       =   0   'False
      ViewID          =   "{0057D0E0-3573-11CF-AE69-08002B2E1262}"
      Location        =   ""
   End
End
Attribute VB_Name = "frmWB"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit


Private Sub Command1_Click()
Dim i As Integer
Dim lret As Long, buff As String
buff = Space$(255)
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
For i = 0 To UBound(arrHwnd)
    lret = GetClassName(arrHwnd(i), buff, 255)
   
    With List1
        .AddItem arrHwnd(i) & vbTab & Left$(buff, lret)
        .Refresh
    End With
   
    EnumChildWindows arrHwnd(i), AddressOf EnumChildProc, 0& 'hWnd
   
Next i

End Sub

Private Sub Form_Load()
    'KPD-Team 2000
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    wb1.Navigate "C:\Mis documentos\Editctls.htm"
End Sub
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6886943
Hi EasyAim, what's up!
0
 

Author Comment

by:EasyAim
ID: 6887297
 Yes, I'm currently using code similar to what you submitted and it works for many of the newer operating systems.  I am after some code that does not use the "oleacc.dll" which 'ObjectFromLresult()' requires.  This DLL is not backward compatible and causes problems on older operating systems (i.e. Win95).
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6887545
couldn't you distribute that dll?
0
 

Author Comment

by:EasyAim
ID: 6888436
 The "oleacc.dll" is problematic when dealing with multiple operating systems especially older Win95/98.  The purpose of this thread is to determine if there is a method of extracting DOM info from foreign webbrowser components without the use of "oleacc.dll".
0
 

Author Comment

by:EasyAim
ID: 6909345
I appreciate all the responses but apparently there isn't a readily available solution other than the use of the "oleacc.dll".
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 7169846
Well, instead of delete this, ask community support to PAQ it. It will no cost you and some other people could get it regardless oleacc.dll's inferno.
0
 

Author Comment

by:EasyAim
ID: 7169899
"ask community support to PAQ"....     What exactly does this mean?
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 7169937
Ask a question in http://www.experts-exchange.com/commspt/ telling what you want to do with this question.
Cheers
0
 
LVL 16

Expert Comment

by:twalgrave
ID: 7753466
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in Community Support that this question is:
- refund/PAQ
Please leave any comments here within the
next seven days.
0
 

Accepted Solution

by:
SpideyMod earned 0 total points
ID: 7809705
per recommendation

SpideyMod
Community Support Moderator @Experts Exchange
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

679 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question