通過實例學習窗口函數---取得IE地址欄的地址
大家知道在 Windows 中,每個程序都是窗口的形式,不管是隱藏的還是顯示的,都可以取得它們的句柄,而每一個程序中的控件又都是一個一個的子窗口,同樣也可以取得它們的句柄,這樣在理論壇上可以取得任意程序中任意位置的值,這裡我們就以取得 IE 浏覽器地址欄中的地址為例子,在下面的例子中我分別自定義的 3 個函數:
1、EnumProc `遍查主窗口
2、GetZiWin `遍查子窗口
3、GetWinText `取得指定句柄的值
這 3 個函數只要做一定的修改,就可以在你任意的程序中單獨使用,最後希望大家通過這個例子能夠掌握窗口函數的基礎技巧。
程序界面:
如圖1所示,裝載1個CommandButton(Caption為取得IE地址欄的地址)、1個ListBox控件,其他屬性全部為默認。
程序代碼:
'Form1.frm 文件
'--------------
Option Explicit
Private Sub Command1_Click()
List1.Clear
EnumWindows AddressOf EnumProc, 0
If List1.ListCount = 0 Then List1.AddItem "沒有啟動 IE 浏覽器"
End Sub
'Module1.bas 文件
'---------------
Option Explicit
'相關 API 函數聲明
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Any, ByVal lParam As Long) _
As Long '枚舉窗口列表中的所有父窗口(頂級和被所有窗口)
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long '取得指定窗口的司法題
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal _
lpClassName As String, ByVal nMaxCount As Long) As Long '為指定的窗口取得類名
Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long '取得窗口句柄
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal _
wMsg As Long, ByVal wParam As Long, lParam As Any) As Long '發送消息
Const GW_CHILD = 5
Const GW_HWNDNEXT = 2
Const WM_GETTEXT = &HD
Const WM_GETTEXTLENGTH = &HE
'遍查主窗口
Public Function EnumProc(ByVal app_hwnd As Long, ByVal lParam As Long) As Boolean
Dim buf As String * 1024
Dim length As Long
Dim title As String
length = GetWindowText(app_hwnd, buf, Len(buf))
title = Left$(buf, length)
'判斷是否為 IE 浏覽器窗口
If InStr(title, " - Netscape") Or InStr(title, " - Microsoft Internet Explorer") Or InStr(title, "Offline Explorer") Then
Call GetZiWin(app_hwnd)
End If
EnumProc = 1
End Function
'遍查子窗口
Public Function GetZiWin(window_hwnd As Long) As String
Dim buf As String
Dim buflen As Long
Dim child_hwnd As Long
Dim children() As Long
Dim num_children As Integer
Dim i As Integer
buflen = 256
buf = Space$(buflen - 1)
buflen = GetClassName(window_hwnd, buf, buflen)
buf = Left$(buf, buflen) '取得子窗口的類名
If Right(buf, 4) = "Edit" Then '判斷是否為地址欄子窗口
GetZiWin = GetWinText(window_hwnd)
Exit Function
End If
num_children = 0
child_hwnd = GetWindow(window_hwnd, GW_CHILD) '取得第 1 個子窗口的句柄
Do While child_hwnd <> 0 '如果有子窗口
num_children = num_children + 1
ReDim Preserve children(1 To num_children)
children(num_children) = child_hwnd
child_hwnd = GetWindow(child_hwnd, GW_HWNDNEXT) '取得下一個兄弟窗口的句柄
Loop
For i = 1 To num_children
Call GetZiWin(children(i))
Next i
End Function
Public Function GetWinText(window_hwnd As Long) As String '取得子窗口的值
Dim txtlen As Long
Dim txt As String
'通過 SendMessage 發送 WM_GETTEXT 取得 IE 地址欄的值
GetWinText = ""
If window_hwnd = 0 Then Exit Function
txtlen = SendMessage(window_hwnd, WM_GETTEXTLENGTH, 0, 0)
If txtlen = 0 Then Exit Function
txtlen = txtlen + 1
txt = Space$(txtlen)
txtlen = SendMessage(window_hwnd, WM_GETTEXT, txtlen, ByVal txt)
GetWinText = Left$(txt, txtlen)
Form1.List1.AddItem GetWinText
End Function
相信大家看了上面的代碼應該知道取得"任意窗口值"的原理,本程序在 VB6.0、Windows 98 下運行良好。
--------------------------------------------------
問如何取得當前運行的IE的標題(存放到字符串中)。
以及如何關閉當前的IE.
首先在工程中加入對Microsoft Internet Controls的引用
代碼:
Dim WithEvents objIEMain As WebBrowser_V1
Dim objIE As Object
Dim dWinFolder As New ShellWindows
Dim objDoc As Object
For Each objIE In dWinFolder
List1.AddItem objIE.Document.Title
List2.AddItem objIE.LocationURL
Next
就可以在List1中列出所有IE文檔的標題了。
下面是關閉其中一個窗口的代碼:
If InStr(objIE.Document.Title, "Apple") Then
objIE.Quit
End If