Solved

OnFocus event for Address Bar in Internet Explorer

Posted on 2004-10-11
8
445 Views
Last Modified: 2010-05-18
Anyone know how to get an OnFocus event going for the address bar in an IE Browser?  So when you click in the address bar you pop a msgbox or something?

Hepen
0
Comment
Question by:Hepen
  • 6
8 Comments
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12283922
Do you mean the address bar in the real IE, because the IE Web control doesn't include an address bar. If it is in the real IE, there could be a method. There is only one ComboBox control (which is the address bar as well) in the IE window. You can try to use FindWindow and GetNextWindow API (90% sure of them) on IE's window, to search and find the combobox controls handle (.hWnd). With this value, you can use the GetWindowText API through a timer to see if the text has changed. If yes, it'll mean that your address bar has a focus. It is more like a Control_TextChanged sort of event rather than Control_OnFocus event. But considering that people click the address bar only when they want to change the location, I guess this approach is ok.

I would have loved to give you the code for searching the combo box control, but I don't have API guide installed as of now. It has a proper example for the same. If you don't have it, you can download it from www.allapi.net. It and Api Viewer have references and examples of all the APIs that can be used with VB.

Hope this info helps in your solving the problem
0
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12284070
Just downloaded API-Guide and got this tutorial. It is for searching and hiding the 'Start Button'. You can modify the code to search the IE window for the combo box.



Const SWP_HIDEWINDOW = &H80
Const SWP_SHOWWINDOW = &H40
Const GW_CHILD = 5
Const GW_HWNDNEXT = 2
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Dim tWnd As Long, bWnd As Long, sSave As String * 250
Private Sub Form_Load()
    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net

    'This code will hide the Start-button
    'Find the taskbar's handle
    tWnd = FindWindow("Shell_traywnd", vbNullString)
    'Search for a child window
    bWnd = GetWindow(tWnd, GW_CHILD)
    Do
        'get the child window's classname
        GetClassName bWnd, sSave, 250
        'We have the handle of the Start button If the classname is 'button'
        If LCase(Left$(sSave, 6)) = "button" Then Exit Do
        'Search the next child
        bWnd = GetWindow(bWnd, GW_HWNDNEXT)
    Loop
    'Hide the start button
    SetWindowPos bWnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
End Sub
Private Sub Form_Unload(Cancel As Integer)
    'Show the start button
    SetWindowPos bWnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW
End Sub
0
 

Author Comment

by:Hepen
ID: 12293506
Yes it is for "Real IE" Window.  I'm trying to use your code still have not got it to work yet but i'm working on it. I was hoping to get some kind of hook on the address bar so when you click inside of it an event triggers of some kind?

Hepen
0
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12294942
I'll just try to write a source code for you. But till then try the following. Use FindWindow API with 'IEFrame' as the Class name. To find a specific window, type its caption in the caption parameter.

Loop till you find the combo box's handle. Use GetWindowText API to check for the change of text.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 17

Accepted Solution

by:
zzzzzooc earned 500 total points
ID: 12295292
>>some kind of hook on the address bar
You can cross-process subclass the window of the ComboBox to accomplish this by having your WindowProc within a DLL so it can be accessed by another process.

Download the example from the below site and copy the DLL into your system folder.
http://www.mentalis.org/vbexamples/vbexample.php?vbexample=DSSUBCLS

Then try the below example.

Form1:
----------------
Private lngHandle As Long
Private Sub Form_Load()
    lngHandle = HookIEAddressBar("Yahoo! - Microsoft Internet Explorer", True)
    If lngHandle <> 0 Then
        'success
    End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
    Call HookIEAddressBar(vbNullString, False, lngHandle)
End Sub


Module1:
----------------
''''
Private Declare Function SubClass Lib "dssubcls" (ByVal HwndSubclass&, Optional ByVal Address& = 0, Optional ByVal OldStyle& = 0, Optional ByVal NewStyle& = 0, Optional ByVal Ext& = 0, Optional ByVal SubClass& = 0) As Long
Private Declare Function SetParams Lib "dssubcls" (Optional ByVal msg& = 0, Optional ByVal wParam& = 0, Optional ByVal lParam& = 0) As Long
Private Declare Function UseSendMessage Lib "dssubcls" (ByVal use&) As Long
'''
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Const WM_MOUSEACTIVATE = &H21
Public Function HookIEAddressBar(ByVal strIECaption As String, ByVal blnHook As Boolean, Optional ByVal lngCurrHandle As Long) As Long
    Dim lngHandle As Long
    If blnHook = True Then
        lngHandle = FindWindow("IEFrame", strIECaption)
        If lngHandle > 0 Then
            'The below finds the "ComboBox" for me (IE6).. will differ
            'upon versions of IE and toolbars/etc
            lngHandle = FindWindowEx(lngHandle, 0, "WorkerW", vbNullString)
            lngHandle = FindWindowEx(lngHandle, 0, "ReBarWindow32", vbNullString)
            lngHandle = FindWindowEx(lngHandle, 0, "ComboBoxEx32", vbNullString)
            lngHandle = FindWindowEx(lngHandle, 0, "ComboBox", vbNullString)
            'lngHandle = FindWindowEx(lngHandle, 0, "Edit", vbNullString)
            If lngHandle > 0 Then
                Call SubClass(lngHandle, AddressOf Callback, 0, 0, 0, 1)
                HookIEAddressBar = lngHandle
            End If
        End If
    Else
        Call SubClass(0)
    End If
End Function
Private Function Callback(ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If wMsg = WM_MOUSEACTIVATE Then
        Form1.Caption = Timer & ": Activated!"
    End If
End Function




Depending on your version of IE and possible toolbars and such installed, the method I use to find the "ComboBox" may fail. Use Spy++ that comes with VS6 and locate it.


0
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12295560
This is what I have so far. But cannot get the text from the handle. Working on it.

Option Explicit
Private Const WM_GETTEXT = &HD
Private Const SWP_HIDEWINDOW = &H80
Private Const SWP_SHOWWINDOW = &H40
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) 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

Dim lhWnd As Long
Dim sSave As String * 255

Private Sub Form_Load()
    'Find the IE Window.Only the first is found.
    lhWnd = FindWindow("IEFrame", vbNullString)
   
    'get handle of child until the combo box is reached
    lhWnd = getHandle(lhWnd, "WorkerW", 7)
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ReBarWindow32", 13)
    Else
        GoTo Out:
    End If
   
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ComboBoxEx32", 12)
    Else
        GoTo Out:
    End If
   
    GetWindowText lhWnd, sSave, 255
   
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ComboBox", 8)
    Else
        GoTo Out:
    End If
   
    GetWindowText lhWnd, sSave, 255
   
    'The combo box has and Edit control (text box!)
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "Edit", 4)
    Else
        GoTo Out:
    End If
   
    'Need to write code here to get text some how
    'Tried many things :(
    sSave = SendMessage(lhWnd, WM_GETTEXT, -1, sSave)
    GetWindowText lhWnd, sSave, 255
    Exit Sub
   
Out:
    MsgBox "There was some error!", vbOKOnly + vbCritical, "Error!"
    Unload Me
End Sub

Private Function getHandle(lParent As Long, ClassName As String, cLength As Integer) As Long
Dim strTemp As String * 255
Dim lTemp As Long

'Search for a child window
lTemp = GetWindow(lParent, GW_CHILD)

If lTemp = 0 Then
    getHandle = 0
    Exit Function
End If
   
Do
    'get the child window's classname
    GetClassName lTemp, strTemp, 255
       
    If Not StrComp((Left$(strTemp, cLength)), ClassName, vbTextCompare) Then
        getHandle = lTemp
        Exit Function
    End If
Out:
    'Search the next child
    lTemp = GetWindow(lTemp, GW_HWNDNEXT)
Loop
End Function
0
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12295820









OK FINALLY GOT THE PERFECT SOLUTION
JUST ADD A TIMER TO A FORM AND COPY THE BELOW CODE. :)











Option Explicit

Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_GETTEXT = &HD

Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) 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 lhWnd As Long
Private dhWnd As Long
Private currAddress As String

Private Sub Form_Load()
    'Find the IE Window.Only the first is found.
    lhWnd = FindWindow("IEFrame", vbNullString)
   
    'get handle of child until the combo box is reached
    lhWnd = getHandle(lhWnd, "WorkerW", 7)
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ReBarWindow32", 13)
    Else
        GoTo Out:
    End If
   
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ComboBoxEx32", 12)
    Else
        GoTo Out:
    End If
   
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "ComboBox", 8)
    Else
        GoTo Out:
    End If
   
    'The combo box has and Edit control (text box!)
    If lhWnd <> 0 Then
        lhWnd = getHandle(lhWnd, "Edit", 4)
    Else
        GoTo Out:
    End If
   
    currAddress = getAddress
    dhWnd = GetDesktopWindow
    Exit Sub
   
Out:
    MsgBox "There was some error!", vbOKOnly + vbCritical, "Error!"
    Unload Me
End Sub

Private Function getHandle(lParent As Long, ClassName As String, cLength As Integer) As Long
Dim strTemp As String * 255
Dim lTemp As Long

'Search for a child window
lTemp = GetWindow(lParent, GW_CHILD)

If lTemp = 0 Then
    getHandle = 0
    Exit Function
End If
   
Do
    'get the child window's classname
    GetClassName lTemp, strTemp, 255
       
    If Not StrComp((Left$(strTemp, cLength)), ClassName, vbTextCompare) Then
        getHandle = lTemp
        Exit Function
    End If
   
    currAddress = getAddress
   
    dhWnd = GetDesktopWindow
Out:
    'Search the next child
    lTemp = GetWindow(lTemp, GW_HWNDNEXT)
Loop
End Function

Private Sub Timer1_Timer()
If currAddress <> getAddress Then
    MessageBox dhWnd, "The text in the address bar has been changed", "Changed", 64
    currAddress = getAddress
End If
End Sub

Private Function getAddress() As String
Dim txtLen As Long
Dim sSave As String
txtLen = SendMessage(lhWnd, WM_GETTEXTLENGTH, 0, 0)
txtLen = txtLen + 1
sSave = Space(txtLen)
txtLen = SendMessage(lhWnd, WM_GETTEXT, txtLen, ByVal sSave)
getAddress = Trim$(sSave)
End Function


This has definitely got to answer your question :)
0
 
LVL 9

Expert Comment

by:Shahid Thaika
ID: 12332888
Hey Hepen,
Does the code solve your problem. Let me know :)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

743 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

10 Experts available now in Live!

Get 1:1 Help Now