代碼沒有使用正確的winapi函數。 FindWindowEx()可以找到子窗口,但MsgBox()顯示的窗口不是子窗口。它是一個頂級窗口,您可以使用FindWindow()找到這種窗口。
但是,該功能不足以找到要關閉的特定消息框。需要一個更好的方法,可以使用EnumThreadWindows()枚舉同一線程擁有的窗口。 MsgBox()的好處是隻有一個這樣的窗口,因爲對話框是模態的。
SendKeys()的確不夠好,它只有在消息框處於前景時才能正常工作。更好的方法是通過發送BM_CLICK消息來實際點擊按鈕。測試代碼,使用訪問形式:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Text
Module Module1
Sub Main()
'' Find the MS-Access host window
Dim access = FindWindow("OMain", Nothing)
If access = IntPtr.Zero Then Throw New Win32Exception()
'' Enumerate the windows owned by the same thread
Dim pid As Integer
Dim tid = GetWindowThreadProcessId(access, pid)
If tid = 0 Then Throw New Win32Exception()
EnumThreadWindows(tid, AddressOf ClickOkButton, Nothing)
End Sub
Private Function ClickOkButton(hWnd As IntPtr, lp As IntPtr) As Boolean
'' Verify the class name is #32770
Dim buf As New StringBuilder(256)
GetClassName(hWnd, buf, 256)
If buf.ToString <> "#32770" Then Return True
'' Find the OK button (control ID 2)
Dim okbutton = GetDlgItem(hWnd, 2)
If okbutton = IntPtr.Zero Then Return True
'' Activate the dialog, just in case
SetActiveWindow(hWnd)
'' Click the button
SendMessage(okbutton, BM_CLICK, IntPtr.Zero, IntPtr.Zero)
'' Done, no need to continue enumerating windows
Return False
End Function
End Module
Friend Module NativeMethods
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Friend Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)>
Friend Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
End Function
Friend Delegate Function EnumThreadDelegate(hWnd As IntPtr, lParam As IntPtr) As Boolean
<DllImport("user32.dll", SetLastError:=True)>
Friend Function EnumThreadWindows(dwThreadId As Int32, lpfn As EnumThreadDelegate, lParam As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Friend Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Friend Function GetDlgItem(ByVal hDlg As IntPtr, id As Integer) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)>
Friend Function SetActiveWindow(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")>
Friend Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByVal lp As IntPtr) As IntPtr
End Function
Friend Const BM_CLICK As Integer = &HF5
End Module
通常的建議是favor UI Automation。
謝謝!我會現在測試,並給予反饋:) – Wilest
我保存這個......上帝知道爲什麼。 – Jaxedin