我创建了一个有2个按钮的表单。一个按钮弹出一个msgbox,另一个按钮从下面列出的frmAPI(代码如下所示)运行。如果我打开msgbox并保持打开然后运行frmAPI,它将列出msgbox及其文本,然后关闭它。这是我期望它做的。如果我打开另一个应用程序并在我的frmAPI仍然运行的情况下在该应用程序中生成一个msgbox,它实际上会列出其他应用程序msgbox和文本,但它不会从其他应用程序关闭msgbox。如果Irun来自其他应用程序的frmAPI并进行相同的测试,则结果会相反。所以简而言之,它只会在同一个应用程序中关闭对话框。
我希望能够从任何应用程序关闭一个对话框,因为它是一个对话框,并且文本符合我的标准。对我做错了什么的帮助?
由于
Imports System.Runtime.InteropServices
Imports System.Text
Partial Public Class TestMSgBoxStuff
Inherits Form
Public Sub New()
InitializeComponent()
End Sub
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindowEx(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function GetWindowText(hWnd As IntPtr, lpString As StringBuilder, nMaxCount As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function GetWindowTextLength(hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SendMessage(hWnd As HandleRef, Msg As UInteger, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("user32", CharSet:=Runtime.InteropServices.CharSet.Auto, SetLastError:=True, ExactSpelling:=True)>
Private Shared Function SetForegroundWindow(ByVal hwnd As IntPtr) As IntPtr
End Function
Private Const WM_IME_NOTIFY As Integer = &H282
Private Const WM_DESTROY As Integer = &H2
Private Const WM_NCDESTROY As Integer = &H82
Private Const WM_CLOSE As Integer = &H10
Private Const IMN_CLOSESTATUSWINDOW As Integer = &H1
Private Const WM_KILLFOCUS As Integer = &H8
Private Const WM_COMMAND As Integer = &H11
Private Sub TestMSgBoxStuff_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim timer As New Timer()
Timer1.Interval = 10000
'detect the MessageBox every seconds
'Timer1.Tick += New EventHandler(Timer1_Tick)
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
'Get the MessageBox handle
Dim handle As IntPtr = FindWindow("#32770", Nothing)
Me.RichTextBox1.AppendText("Handle: " + handle.ToString() + vbLf)
'Get the Text window handle
Dim txtHandle As IntPtr = FindWindowEx(handle, IntPtr.Zero, "Static", Nothing)
Me.RichTextBox1.AppendText(vbTab & "text handle: " + txtHandle.ToString() + vbLf)
Dim len As Integer = GetWindowTextLength(txtHandle)
Dim sb As New StringBuilder()
'Get the text
GetWindowText(txtHandle, sb, len + 1)
Me.RichTextBox1.AppendText(vbTab & "text: " + sb.ToString() + vbLf & vbLf)
Me.RichTextBox1.ScrollToCaret()
SetForegroundWindow(handle)
'close the messagebox WM_CLOSE
Dim lResults As Integer = SendMessage(New HandleRef(Nothing, handle), WM_NCDESTROY, IntPtr.Zero, IntPtr.Zero)
End Sub
End Class
答案 0 :(得分:1)
您可能遇到User Interface Privilege Isolation。这会阻止您的邮件进入更高权限的过程。另请参阅ChangeWindowsMessageFilter()
我建议尝试发送WM_COMMAND
而不是WM_CLOSE
; WM_COMMAND
通常由系统更温和地对待,并且可以通过。使用BN_CLICKED作为WPARAM的高位字和IDOK作为低位字(假设它有一个OK按钮),以及LPARAM中OK按钮的句柄。其他按钮消息是here。