Только для сообщений окно не получает PostMessage - PullRequest
2 голосов
/ 18 ноября 2010

У меня есть приложение Vb.net, созданное третьей стороной, которое я должен контролировать, используя внешние ресурсы из имитируемой среды, и не должен взаимодействовать с рабочим столом. Чтобы имитировать входные данные, которые пользователь обычно вводил бы со специального экрана с определенными клавишами вокруг него, я создал библиотеку контрольных тестов, чтобы управлять им и отправлять изображение формы в .bmp. Форма не отображается и отображается на панели задач, вывод bmp будет отображаться в смоделированной среде.

Использование PostMessage и sendKeys работают хорошо, пока у меня нет, но ShowInTaskbar = False для основной формы. После многих чтений и испытаний я выучил достаточно, чтобы попробовать то, что, кажется, единственное, что сработало бы. Я создал форму, которую я установил, используя параметр HWND_MESSAGE, это должно создать Windows только для сообщений, которая должна получать postMessage, и подклассить ее события. msdn .

StackOverflow уже об этом

К сожалению, я не могу заставить его работать, и я надеялся, что кто-нибудь скажет мне, что я делаю неправильно. Я тестировал несколько различных способов, найденных в Интернете, по поводу .net, и если не считать зайдя в ветку сообщений заглянуть и кормить (может быть (может быть) моя последняя надежда), они все, кажется, работают, пока я не заберу формы из панели задач.

Хорошо, вот код:

MsgOnly.vb

Public Class MsgHandling

DllImport ("user32.dll", SetLastError: = True, CharSet: = CharSet.Auto)> _ Открытая общая функция SetParent (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) Как IntPtr Конечная функция

Частный общий HWND_MESSAGE As 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 Ответ

2 голосов
/ 19 ноября 2010

Я нашел работу вокруг.Кажется, проблема в том, что дескриптор окна не найден в функциях поиска.Я пробовал несколько способов, но так как только сообщения не перечисляются, я не могу зациклиться, или, по крайней мере, мне это не удалось.

Поэтому я создаю файл с дескриптором, который внешняя программа читаети использовать этот дескриптор для создания PostMessage.Это работает хорошо на данный момент.Я бы хотел найти лучший способ, но, по крайней мере, у меня есть что предложить в качестве решения.

Я все еще открыт для предложения или другого возможного обходного пути:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...