仅消息窗口未接收PostMessage

时间:2010-11-17 21:03:04

标签: vb.net winapi winforms-interop .net-3.5

我有一个由第三方制作的Vb.net应用程序,我需要使用模拟环境中的外部资源进行控制,并且不得与桌面交互。为了模拟用户通常使用特定屏幕输入的输入,我已经构建了一个测试控件库来控制它并将表单图像发送到.bmp。表单无法显示并显示在任务栏中,bmp输出将由模拟环境显示。

使用PostMessage和sendKeys只要我没有,但主表单的ShowInTaskbar = False。经过多次阅读和阅读测试,我已经学到了足够的东西来尝试看起来唯一可行的东西。我创建了一个使用HWND_MESSAGE参数设置的表单,这应该创建一个Message-Only Windows,它应该接收postMessage,并将其子类化为事件。msdn

StackOverflow already about this

不幸的是,我似乎无法让它工作,我希望有人可以告诉我我做错了什么。我一直在测试通过网络发现的几种不同的方式.net,以及进入消息线程偷看和提供(也许(可能是)我的最后希望),它们似乎都有效,直到我从任务栏中取出表格。

好的,这是代码:

MsgOnly.vb

Public Class MsgHandling
     

DllImport(“user32.dll”,SetLastError:= True,CharSet:= CharSet.Auto)> _   公共共享函数SetParent(ByVal hWndChild作为IntPtr,   ByVal hWndNewParent As IntPtr)As   IntPtr的   结束功能

     

私有共享HWND_MESSAGE为IntPtr =新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

我不确定我现在可以提供的其他细节。任何人都没有找到任何想法或方法吗?

感谢任何输入

1 个答案:

答案 0 :(得分:2)

我找到了一个解决方法。似乎问题来自于使用搜索功能找不到窗口句柄的事实。我尝试了几种方法,但由于没有枚举消息,我无法循环,或者至少我没有成功。

所以我创建了一个带有句柄的文件,外部程序读取和使用句柄来创建PostMessage。这适用于现在。我希望我能找到更好的方法,但至少我有一些建议作为解决方案。

我仍然接受建议或其他可能的解决方法:)。