Solved

WebBrowser detection

Posted on 2002-03-10
21
696 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
Comment Utility
I think you could detect webbrowser control if you set registerasbrowser property.
0
 
LVL 27

Expert Comment

by:Ark
Comment Utility
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
Comment Utility
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
 
LVL 27

Expert Comment

by:Ark
Comment Utility
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
Comment Utility
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
Comment Utility
It is not the only way but it depends upon from what window you need to do it.
0
 

Author Comment

by:EasyAim
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
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
Comment Utility
Hi EasyAim, what's up!
0
 

Author Comment

by:EasyAim
Comment Utility
 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
Comment Utility
couldn't you distribute that dll?
0
 

Author Comment

by:EasyAim
Comment Utility
 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
Comment Utility
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
Comment Utility
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
Comment Utility
"ask community support to PAQ"....     What exactly does this mean?
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
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
Comment Utility
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
Comment Utility
per recommendation

SpideyMod
Community Support Moderator @Experts Exchange
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

744 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now