我有一个第三方制作的 Vb.net 应用程序,我需要使用模拟环境中的外部资源进行控制,并且不能与桌面交互。为了模拟用户通常从带有特定键的特殊屏幕输入的输入,我构建了一个测试控件库来控制它并将表单图像发送到 .bmp。表单不可见并显示在任务栏中,bmp输出将由模拟环境显示。
只要我不使用 PostMessage 和 sendKeys 就可以很好地工作,但 ShowInTaskbar = False 对于主表单。经过多次阅读和测试,我已经学到了足够多的东西来尝试似乎唯一可行的方法。我创建了一个我使用 HWND_MESSAGE 参数设置父级的表单,这应该创建一个仅消息窗口,它应该接收 postMessage,并将其子类化为事件。微软的。
不幸的是,我似乎无法让它工作,我希望有人能告诉我我做错了什么。我已经测试了几种通过网络找到的关于 .net 的不同方法,并且没有进入消息线程偷看和提要(也许(也许是)我最后的希望),它们似乎都可以工作,直到我将表格从任务栏中取出。
好的,下面是代码:
MsgOnly.vb
Public Class MsgHandling
DllImport("user32.dll", SetLastError:=True,CharSet:=CharSet.Auto)> _ Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr End Function
私有共享 HWND_MESSAGE As IntPtr = New IntPtr(-3)
Public Event CallBackProc(ByRef m As Message) Public Sub setParent() SetParent(Me.Handle, HWND_MESSAGE) End Sub Protected Overrides Sub WndProc(ByRef m As Message) RaiseEvent CallBackProc(m) 'then RaiseEvent MyBase.WndProc(m) End Sub End Class
表单中的部分子类化(不能显示比处理子类化、隐私问题的更多内容。希望这就足够了)
Public WithEvents Msg As New MsgHandling
Private Sub XXXXX_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'----snips
Msg.setParent()
'----snips
end sub
Private Sub CallBackProc(ByRef m As System.Windows.Forms.Message) Handles Msg.CallBackProc
Me.Text = "Rx events " & m.LParam.ToString() & " " & m.WParam.ToString()
WndProc(m)
End Sub
测试表格
Public Class Form1
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
Public Shared Function SetWindowPos( _
ByVal hWnd As IntPtr, _
ByVal hWndInsertAfter As IntPtr, _
ByVal X As Int32, _
ByVal Y As Int32, _
ByVal cy As Int32, _
ByVal uFlags As Int32) _
As Boolean
End Function
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function AllowSetForegroundWindow Lib "user32" Alias "AllowSetForegroundWindow" (ByVal dwProcessId As Integer) As Boolean
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
Public myProcess As Process = New Process()
Private Const WM_KEYDOWN As Long = 100
Private Const WM_RBUTTONDOWN As Long = 204
Public Shared HWND_MESSAGE As IntPtr = New IntPtr(-3)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myProcess.StartInfo.FileName = "...\XXXXXX.exe" 'Not real name
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.EnableRaisingEvents = True
AddHandler myProcess.Exited, AddressOf Me.SendKeysTestExited
myProcess.Start()
End Sub
Friend Sub SendKeysTestExited(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim myRxProcess As Process = DirectCast(sender, Process)
myRxProcess.Close()
End Sub
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
Dim tHwnd As Long
Dim rslt As Boolean
If myProcess.Responding Then
tHwnd = FindWindowEx(HWND_MESSAGE, 0, 0, 0)
PostMessage(HWND_MESSAGE, WM_RBUTTONDOWN, 0, "TEXT TO SEND")
Else
myProcess.Kill()
End If
End Sub
Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
myProcess.Close()
End Sub
End Class
不太确定我现在可以提供哪些其他细节。我还没有找到任何想法或方法?
感谢您的任何意见