vb.net使用FindWindowex在另一个应用程序中查找messagebox

vb.net使用FindWindowex在另一个应用程序中查找messagebox,第1张

概述我有一个visual basic应用程序需要找到Microsoft Access,它有一个消息框,然后Send Enter到消息框. 我跟着这篇文章(FindWindow FindWindowEx). 它找到Access并将其带到前台,但它不想找到消息框并将其带到前面: Public Class Form1 Private Declare Function SetForegroundWindo 我有一个visual basic应用程序需要找到Microsoft Access,它有一个消息框,然后Send Enter到消息框.

我跟着这篇文章(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所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1239115.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-06
下一篇2022-06-06

发表评论

登录后才能评论

评论列表(0条)

    保存