
我跟着这篇文章(FindWindow FindWindowEx).
它找到Access并将其带到前台,但它不想找到消息框并将其带到前面:
Public Class Form1 Private Declare Function SetForegrounDWindow lib "user32" (ByVal hwnd As IntPtr) As Long Private Declare auto Function FinDWindow lib "user32.dll" ( _ ByVal lpClassname As String,_ ByVal lpWindowname As String _ ) As IntPtr Private Declare auto Function findwindowex lib "user32.dll" ( _ ByVal hwndParent As IntPtr,_ ByVal hwndChildAfter As IntPtr,_ ByVal lpszClass As String,_ ByVal lpszWindow As String _ ) As IntPtr Private Sub Form1_Load(sender As Object,e As EventArgs) Handles MyBase.Load Dim hWnd As IntPtr hWnd = FinDWindow("OMain",nothing) MsgBox(hWnd) 'FINDS 1640402 Dim hWndChild1 As IntPtr = _ findwindowex(hWnd,IntPtr.Zero,"#32770 (Dialog)","Microsoft Access") MsgBox(hWndChild1) 'FirsT PROBLEM IT FINDS ZERO HERE Dim hWndChild1button As IntPtr = _ findwindowex(hWndChild1,"button","OK") MsgBox(hWndChild1button) 'ALSO FINDS ZERO HERE If hWndChild1button <> IntPtr.Zero Then SetForegrounDWindow(hWndChild1button) SendKeys.SenDWait("{Enter}") End If End SubEnd Class 解决方法 代码未使用正确的winAPI函数. findwindowex()可以找到子窗口,但MsgBox()显示的窗口不是子窗口.它是一个顶级窗口,您可以使用FinDWindow()找到它.
但该功能不足以找到您要关闭的特定消息框.需要一种更好的方法,您可以使用的方法是使用EnumThreadwindows()枚举同一线程拥有的窗口.关于MsgBox()的好处是,由于对话框是模态的,因此只有一个这样的窗口.
SendKeys()也不够精确,如果消息框在前台,它只能正常工作.更好的方法是通过向BM_CliCK消息发送实际单击按钮.使用Access表单测试的代码:
imports System.Runtime.InteropServicesimports System.ComponentModelimports System.TextModule 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) '' Done,no need to continue enumerating windows Return False End FunctionEnd ModuleFrIEnd 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",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 = &HF5End Module 通常的建议是favor UI Automation.
总结以上是内存溢出为你收集整理的vb.net使用FindWindowex在另一个应用程序中查找messagebox全部内容,希望文章能够帮你解决vb.net使用FindWindowex在另一个应用程序中查找messagebox所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)